C ++用のLINQライブラリはありますか?[閉まっている]


82

何らかの方法でLINQをC ++に移行させるための、プラットフォームに依存しない(CLIではない)動きはありますか?

つまり、世界中のサーバーフレームワークの大部分がUNIXのフレーバーで実行されており、UNIX上のLINQ for C ++にアクセスできると、多くの人が喜ぶでしょう。


1
モナド(IEnumerable <>とその拡張メソッドのセット)を意味しますか?あなたはそれの言語的側面を意味しますか?LINQ-to-SQLのことですか?
yfeldblum 2008年

LINQ-SQLの部分は私が本当に欲しい部分ですが、それはLINQの言語とモナドに依存します。
ロバートグールド

2
男、これは本当に役立つ質問です!このような質問は閉じないでください。
j00hi

私の実装を確認してくださいgithub.com/DevUtilsNet/linqcpp他の実装を分析し、自分に合わないすべての欠陥を削除しました。
antwoord

回答:


34

HongJiangによるLinq ++は良いスタートのように見えます。その構文は、CLinqよりもLinqにはるかに近いものです。pfultz2によるLinqも面白そうに見えますが、C ++ 11コンパイラが必要です。


1
いいね。c ++ 11バージョンは、彼の生の理解の例で「ボイラープレートコード」を回避するためにフェニックスを使用する必要があったとしても、非常に興味深いようです。
KitsuneYMG

うーん、SQLデータベースをサポートしているとは思いません。
Arne 2014

21

これは、テンプレートC ++ LINQライブラリの私のソリューションです。
ソースコードはこちらです:Boolinq
各機能には多くのテストがあります。
私は今それに取り組んでいます。

コメントはありますか?
アドバイスかもしれませんか?

更新:プロジェクトはに移動しました https://github.com/k06a/boolinqに、バージョン2.0になりました。ソースコードは700行のみです:)


に関するコンパイルエラーのため、Qt5.9.1でboolinqを使用できませんでしたQ_FOREACH。おそらくQ_FOREACH段階的に廃止されたためです。
ニコラ・マリーズビック

@NikolaMaleševićは、include boolinq.h:の直前、include:の#define foreach for_each後に#undef foreach、Qtヘッダーを含めるように定義してみてください。
k06a 2017

1
本当にBoolinqが好きです!groupByを追加してください
ピングー


8

http://cpplinq.codeplex.com/は非常に優れた実装です。
著者から:
CppLinqの動機は、boolinqとNative-RXの両方が演算子に基づいているように見えることです。」リスト関数を作成します。問題は「。」ということです。演算子は、C ++でオーバーロードできないため、これらのライブラリを自分の設計の関数で拡張するのが難しいということです。私にとってこれは重要です。CppLinqは、オーバーロード可能な演算子>>に基づいているため、CppLinqを拡張可能にすることができます。



7

私は小さなライブラリcppLinqを書きましたIEnumerable <>とそのLINQ演算子を再実装を。これは単なる実験です。今のところ、Windowsでのみ機能し(コルーチンはWin32ファイバーで実装されています)、VS11のDev Previewでのみビルドされます(ラムダ式を多用します:-))。

これにより、次のようなコードを記述できます。

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
ご意見をありがとうございます。はい、上記のサンプルのラムダは少し改善される可能性がありますが、それは単なる詳細です。ただし、shared_ptrsとpointersについて何ができるかわかりません。アイデアは、遅延評価とデータパイプラインを提供するために、コルーチンを使用してイテレータブロックを実装することでした。これは、C#での実装方法とまったく同じです。たとえば、ソースでは、STLコンテナーからデータを「生成」するものを使用できますが、コルーチンからデータを生成するIEnumeratorsのように動作する必要があるコンポーネントのパイプがあります。LINQのC ++バージョンではどのインターフェイスを念頭に置いていますか?
パオロセヴェリーニ2012

5
静的な式テンプレートベースのアプローチは、私が考えていたものです。それを読んでください。
xeo 2012

本当にありがとう、Xeo!式テンプレートは非常に興味深いものです。私は間違いなくそれらについてもっと学びたいと思います。LINQの意味で遅延評価を実装するために使用できると思いますか(シーケンスは一度に1つのアイテムを「生成」しますか?)これがLINQの要点だと思うので、既存のコンテナーを変更したくないので、 LINQ式に連結されたすべての演算子の出力である一時コンテナーのすべてのデータを一度に生成したくない。怠惰である必要があります。そうでない場合は、LINQを気にする必要はありません。すべて、stl、stdアルゴリズム、ラムダで実行できます。
パオロセヴェリーニ2012

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);

フィードバックは大歓迎です。


とてもよくできていて、私はそれが好きです。
ティムシルベスター

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、またはそれが呼び出さautoれることになったものには、型推論を可能にするという新しいキーワードがあります。そして、はい、C ++用のラムダが登場するでしょう。また、グーグルですばやく検索すると、これが明らかになりました、CLinq


2

これがc ++ 11(中国語)でのc ++-linqの実装です:

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

「遅延クエリ」、「スタックベース」(演算子newをできるだけ使用しない)、「コピーセマンティック」(バックアップ後にクエリを複数回繰り返すことができる)などの機能をサポートします。

また、「from、select、where、cast、range、all、any、cast、average、contain、count、first、last、head、tail、groupBy、takeUntil、skipUntil、max、min、reduce、」など、数十の関数をサポートしています。一意、並べ替え、ランダム、交差、_union "。

私のコードは、誰でも理解して拡張できるほど単純だと思います。


-4

C ++には、ラムダ式などを処理するためのコンパイラーシュガーがないと思います。そのため、それは起こりません。


5
C ++ 0Xにはラムダがあるので、理論的には可能ですが、そう簡単な作業ではありません。
ロバートグールド

7
Boost.Phoenixライブラリは、プリコンパイラのトリックなしでC ++にLambdasを追加します。tinyurl.com/d4y9se [boost.org]を参照してください。もちろん、C ++ 0xを使用すると、このようなものの多くが簡単になります。C ++ 0xでLINQを行うにはどのように素晴らしい記事tinyurl.com/d9zlsc [blogspot.com]
JK。

3
LOL、boost :: lambda、いくつかのテンプレートトリック、そしてある場合にはプリコンパイラの助けを借りて、私は次の構文を思いつくことができました:from(v).where(&_1 ->* &Person::age >= 18).order_by(Person, age).top(5).order_by(Person, name)std :: vector <Person>から5人の最年少の大人を選択してそれらを返すアルファベット順。... C ++は、タスクのために適切であることを言うだろう、私はそう
アンドレアスMagnusson氏

1
@Andreas、ああ、あなたはLINQの超能力を使ってLINQをSQLクエリに変換していると思いました。その場合、ASTが必要であり、C#で取得します。C ++ AFAIKではそれを行うことはできません。
Elazar Leibovich 2011年

1
@ Elazar&@ Andreas-LINQには実際には2つのフレーバーがあります。1つはAndreasのように動作し、もう1つはSQLまたはその他のクエリ表現を作成するためにコードで再解釈できる式ツリー(完全なASTのサブセット)を使用します。後者のフォームの詳細についてExpression<T>は、C#のドキュメントを参照してください。
ドリューノアケス2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.