C++是否有类似于.NET的LINQ功能?

3

是否可以在C++中获得类似于.NET的LINQ的功能?这需要语言扩展还是可以通过一些非常聪明的宏来完成?或者甚至可以通过像Qt的moc(元对象编译器)这样的工具来完成?是否存在用于C ++的现有LINQ实现,如果有,它们是什么?


4
你的问题不应该是“我如何将语言X的功能转移到语言Y中”。那是一个无意义的问题,因为它们是不同的语言,要学习语言Y的做法。应该问“我如何在语言Y中解决问题A?” - GManNickG
3
@Cheryl: 我在哪里说过它没用?关键是,尝试让一种语言做它无法帮助你完成的事情是没有用的。当有人使用语言X进行编程时,他们应该忘记任何其他语言的知识。拥抱你的语言,不要试图将它变成其他语言。 - GManNickG
3
@GMan:“当某人使用语言X进行编程时,他们应该忘记关于任何其他语言的一切。”<< 这是我在StackOverflow上听到的最荒谬的说法。我完全不同意。 - one-zero-zero-one
4
如果Boost的开发者们采用了这种态度,今天我们就没有boost::lambdaboost::parametersboost::phoenix等库。所有这些库都试图模拟其他一些语言本地支持的功能。@GMan提到:"拥抱你的语言,不要试图将其变成其他语言。" - one-zero-zero-one
2
@GMan:RAII vs finally 是一个语义相关的例子。 RAII 很适合 C++ 语言的语义,finally 不适合。 finally 很适合 C# 的语义,RAII 则不适合。这是一个不建议从其他语言借鉴或尝试模拟想法的例子。 - one-zero-zero-one
显示剩余12条评论
3个回答

6

请查看 CLinq (这里这里) 或 Linq++ (这里)。还可以尝试 p-stade (这里),但它使用的是 STL,并且界面与 LINQ 不同,但相当完整。


4
CLinq适用于C++/CLI,而C++/CLI并不等同于C++。 - missingfaktor
@Missing Faktor:我在实现CLinq时使用的技术也适用于普通的C++。它之所以是C++/CLI,是因为我想使用现有的.NET API(LINQ库),但这也可以在C++中重新实现。CLinq基本上只是使用模板(而不是泛型)和常规运算符重载来实现的。 - Tomas Petricek

2

使用这个 C++11 的 Linq 库,你可以使用类似 Linq 的语法进行列表推导:

std::vector<int> numbers = { 1, 2, 3, 4 };
auto r = LINQ(from(x, numbers) where(x > 2) select(x * x));
for (auto x : r) printf("%i\n", x);

它使用预处理器来解析fromwhereselect子句,并使用Boost.Range适配器将其转换为等效的形式:
auto r = numbers 
        | boost::adaptors::filtered([](int x) { return x > 2; }) 
        | boost::adaptors::transformed([](int x) { return x * x; });

1
在C++中实现类似于.NET的LINQ的功能是可能的吗?这是否需要语言扩展,还是可以使用一些非常聪明的宏来完成?
C++宏的功能不足以实现像LINQ这样复杂的东西。
要以库的形式实现类似于LINQ的系统,语言需要:
- 良好的嵌入式DSL能力。 - 惰性求值 - 持久化集合 - Lambda表达式
在C++中,嵌入式DSL看起来非常丑陋,这要归因于该语言的严格语法和语义(例如,看看Boost.Spirit,然后再看看来自DSL友好语言(如Haskell)的等效库)。您可以通过boost::phoenix获得惰性求值。除了FC++(相当不完整)之外,没有可用于C++的持久化集合库。Lambda表达式将在下一个标准的C++中出现。
即使有一天有人使用上述成分成功地为C++创建了类似于LINQ的系统,那个系统也不会像.NET中的LINQ那样好。所以,是的,这是“可能的”,但“不太实用”。 :)
甚至可以通过像Qt的moc(元对象编译器)这样的工具来实现吗?
这是完全可能的。但那还真不算是C++,对吧? ;)
是否存在任何现有的C++ LINQ实现,如果有,它们是什么?
已经有一些尝试朝这个方向发展了(正如其他先生在这里指出的)。虽然它们都无法与“真正”的LINQ相提并论,但仍值得一看。 :)
编辑: 显然我错了,“实用”这一点。请看Yassin答案中的p-stade链接,这是一个巧妙地利用强大的C++抽象所能实现的绝佳示例。 :-)

1
就这一点而言,我不太同意,因为你可以使用构建器模式来完成:mybuilder.select("Trees").from("Sprites").where("Height > 4"); - wheaties
2
@wheaties:那你会用这些字符串做什么呢?要想对这些字符串进行任何有用的操作,你需要反射——而 C++ 并没有这个功能。 - one-zero-zero-one
1
@Cheryl Vincent 我认为这对于在 SQL 上使用 LINQ 会非常有效。 - wheaties
2
@wheaties:...那么关于集合的LINQ呢? - one-zero-zero-one
1
你的意思是在C++中尝试实现LINQ并不值得麻烦,因为C++不支持LINQ吗?哇。一个新的方法可能是看看C++能做什么,并探索这个方向,利用它本身已经提供的特性。 - GManNickG
1
@GMan:看一下Yassin的回答中的p-stade链接。看起来相当不错和有用。 - one-zero-zero-one

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接