有C ++的LINQ库吗?[关闭]


82

是否有任何与平台无关的(而非CLI)运动使LINQ以某种方式适用于C ++?

我的意思是说,全世界很多服务器框架都运行在UNIX风格上,并且可以在UNIX上访问LINQ for C ++。


1
您是说monad(IEnumerable <>及其扩展方法集)吗?您的意思是语言吗?您是说LINQ-to-SQL吗?
yfeldblum

好吧,LINQ-SQL部分是我真正想要的部分,但这取决于LINQ的语言和monad。
罗伯特·古尔德

2
伙计,这是一个非常有帮助的问题!请不要关闭此类问题!
j00hi

请检查我的意思github.com/DevUtilsNet/linqcpp我分析了其他实现,并删除了所有不适合我的缺陷。
antwoord

Answers:


34

Hong Jiang的Linq ++看起来是个不错的开始。它的语法比CLinq的语法更接近Linq。pfultz2的Linq看起来也很有趣,但是它需要C ++ 11编译器。


1
真好 即使他的原始理解示例应该使用Phoenix来避免“样板代码”,C ++ 11版本也似乎非常有趣。
KitsuneYMG,2012年

嗯,我看不到他们支持SQL数据库。
Arne 2014年

21

这是我的模板C ++ LINQ库的解决方案。
源代码在这里:Boolinq
每个功能都有很多测试。
我正在研究它。

任何意见?
可能是建议?

更新:项目移至https://github.com/k06a/boolinq,现在具有仅700行源代码的2.0版:)


由于有关的编译错误,我无法将Boolinq与Qt 5.9.1一起使用Q_FOREACH。可能是由于Q_FOREACH被淘汰。
NikolaMalešević17年

@NikolaMalešević,您可以尝试在include boolinq.h之前定义:#define foreach for_each在include:之后#undef foreach,然后包括Qt标头。
k06a

1
真的很喜欢Boolinq!请添加groupBy
pingu

18

微软刚刚宣布他们已经为C和C ++构建了LINQ。不过尚不可用。

2012年11月6日更新:

Microsoft Open Technologies,Inc.现在已经发布开源(Apache License 2.0)了许多相关的库,包括LINQ实现(Ix ++)及其新的Reactive Extensions(Rx ++)库。


8

http://cpplinq.codeplex.com/是一个非常好的实现。
来自作者:
CppLinq的动机是boolinq和Native-RX似乎都基于运算符。” 组成列表功能。问题在于“。” 运算符是它不能在C ++中重载,这使得很难用我自己设计的功能扩展这些库。对我来说,这很重要。CppLinq基于运算符>>,该运算符是可重载的,因此可以使CppLinq可扩展。



7

我编写了一个小的库cppLinq,它重新实现了IEnumerable <>及其LINQ运算符。这只是一个实验;目前,它仅在Windows上可用(协同程序是使用Win32光纤实现的),并且仅使用VS11的Dev Preview进行构建(它大量使用了lambda表达式:-)。

它允许编写如下代码:

auto source = IEnumerable<int>::Range(0, 10);

auto it = source->Where([](int val) { return ((val % 2) == 0); })
                ->Select<double>([](int val) -> double { return (val * val); }));

foreach<double>(it, [](double& val){
    printf("%.2f\n", val);
});

7
将C#盲目转换为C ++不会对任何人有任何好处。为什么需要接口?如果您删除了这些内容,那么您还将删除所有这些无用的分配和poiner语法。而且,如果不能这样做,请至少将shared_ptrs切换为unique_ptrs,因为后者可以转换为前者,反之亦然。另外,样式很复杂,您不需要-> double返回类型。只需让隐式转换发挥作用即可。
Xeo 2012年

2
谢谢你的评论。是的,上面示例中的lambda可以改善一点,但这只是一个细节。不过,我不确定该如何处理shared_ptrs和指针。这个想法是用协程实现迭代器块,确切地说,它们是如何在C#中实现的,以便提供惰性评估和数据管道。例如,从源头上讲,我们可以拥有一些从STL容器“生成”数据的东西,但是随后我们有了一系列必须像IEnumerators一样工作的组件,它们从协例程中产生数据。对于LINQ的C ++版本,您打算使用什么接口?
Paolo Severini'2

5
我想到的是一个基于静态表达式模板的方法。继续阅读。
Xeo 2012年

谢谢Xeo,真的!表达式模板非常有趣,我一定会尝试进一步了解它们。您认为它们可以用于实现LINQ意义上的惰性评估(一次将序列“屈服”一个项目吗?)因为我认为这是LINQ的要旨:您不想修改现有容器,而您不想立即生成临时容器的所有数据,这些数据是LINQ表达式中并置的所有运算符的输出。它必须是懒惰的,否则无需打扰LINQ,您可以使用stl,std算法和lambda来完成所有操作。
Paolo Severini'2

2
好吧..只需在取消引用迭代器的过程中应用所需的任何内容即可。另外,看看Boost.Range
Xeo 2012年

3

这是另一个替代方案,只是将boost和stl算法包装在一起,因此您可以获得这些实现的大部分性能优势。

它是这样的:

std::vector<int> xs;
auto count = from(xs)
   .select([](int x){return x*x;})
   .where([](int x){return x > 16;})
   .count();
auto xs2 = from(xs)
   .select([](int x){return x*x;})
   .to<std::vector<int>>();

请注意,某些方法返回空范围的代理,例如

std::vector<int> xs;
auto max = from(xs)
   .select([](int x){return x*x;})
   .where([](int x){return x > 16;})
   .max()
   .value_or(default_max_value);

欢迎反馈。


做得很好,我喜欢。
蒂姆·西尔维斯特2015年

3

实际上,如果您只想使用Linq进行列表理解,则可以使用此Linq库。它需要C ++ 11(尽管可以在MSVC 2010中使用)和Boost。使用该库,您可以编写linq查询,如下所示:

struct student_t
{
    std::string last_name;
    std::vector<int> scores;
};

std::vector<student_t> students = 
{
    {"Omelchenko", {97, 72, 81, 60}},
    {"O'Donnell", {75, 84, 91, 39}},
    {"Mortensen", {88, 94, 65, 85}},
    {"Garcia", {97, 89, 85, 82}},
    {"Beebe", {35, 72, 91, 70}} 
};

auto scores = LINQ(from(student, students) 
                   from(score, student.scores) 
                   where(score > 90) 
                   select(std::make_pair(student.last_name, score)));

for (auto x : scores)
{
    printf("%s score: %i\n", x.first.c_str(), x.second);
}

将输出:

Omelchenko score: 97
O'Donnell score: 91
Mortensen score: 94
Garcia score: 97
Beebe score: 91

2

C ++ 0x或它最终被调用的任何东西,确实有一个名为autotype的新关键字。是的,C ++将会有lambda的到来。此外,谷歌快速搜索显示了这一点CLinq


2

这是我用c ++ 11(中文)实现的c ++-linq:

http://www.cnblogs.com/cbscan/archive/2012/10/20/2732773.html

它支持“延迟查询”,“基于堆栈”(尽可能少使用new运算符),“复制语义”(因此您可以在备份后多次迭代查询)等功能。

它还支持数十种功能,包括“从,选择,何处,强制转换,范围,所有,任何,投射,平均,包含,计数,第一,最后,头,尾,groupBy,takeUntil,skipUntil,max,min,reduce唯一,排序,随机,相交,_联盟”。

我认为我的代码很简单,任何人都可以理解和扩展。


-4

我不认为C ++具有编译器糖来处理诸如lambda表达式之类的事情,所以不,那不会发生。


5
C ++ 0X具有lambda,因此从理论上讲应该是可能的,但是是的,这并非易事。
罗伯特·古尔德

7
Boost.Phoenix库还将Lambdas添加到C ++,而无需任何预编译技巧。参见tinyurl.com/d4y9se [boost.org]当然,使用C ++ 0x可以使很多这些工作变得容易!一篇不错的文章,介绍如何使用c ++ 0x tinyurl.com/d9zlsc [blogspot.com]
jk

3
大声笑,借助于boost :: lambda,一些模板技巧,在某种情况下预编译器,我能够提出以下语法:from(v).where(&_1 ->* &Person::age >= 18).order_by(Person, age).top(5).order_by(Person, name)从std :: vector <Person>中选择五个最年轻的成年人并返回他们按字母顺序。因此,我想说C ++足以胜任这项任务……
Andreas Magnusson

1
@Andreas,哦,我想您是在使用LINQ的超能力将LINQ转换为SQL查询。在这种情况下,您需要使用C#并获取AST。您无法在C ++ AFAIK中做到这一点。
Elazar Leibovich

1
@Elazar和@Andreas-LINQ实际上有两种口味。一个像我相信Andreas的一样运作,另一个使用表达式树(完整AST的子集),可以在代码中重新解释以创建SQL或其他查询表示形式。有关后一种形式的更多信息,请Expression<T>参见C#文档。
Drew Noakes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.