2011-11-14 12 views
7

反復処理は動作します:のstd :: for_each、C++ 11

std::vector<int> collection = {2, 3, 4, 5435345, 2}; 
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;}); 

ではなく、オーバーセットは(コンパイルエラー):

std::set<int> collection = {2, 3, 4, 5435345, 2}; 
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;}); 

をなぜすることができます」私はstd::setstd::for_eachで繰り返しますか?

ボーナス質問: また、私はなぜこれが自動的に推定することはできません、auto&にラムダの引数でint&を変更したいですか?

答えて

19

std::set<T>::value_typeT constであり、Tではない。その結果、ラムダの引数は値のタイプ(つまりコピー)またはint const&(技術的にはint const volatile&)でなく、int&でなければなりません。すなわち、この作品:

std::set<int> collection{2, 3, 4, 5435345, 2}; 
std::for_each(
    collection.begin(), 
    collection.end(), 
    [](int const& i) { std::cout << i << std::endl; } 
); 

ボーナス質問:また、私はauto&にラムダの引数にint&を変更したい、なぜこれが自動的に推論することができないのですか?

標準では言えないので、歴史的には、これはラムダとコンセプトの間の過度に複雑な相互作用(コンセプトがドラフトから削除される前)に起因すると考えています。 しかし、最初の欠陥が新しい(C++ 11)標準に報告しているという噂がありますので、来年1〜2年以内に選択したコンパイラにこの機能が追加されている可能性があります。 EDIT:まあ、C++ 14は多型ラムダを持っています...

+0

あなたはそれを聞いたことがありますか? Herb sutterのブログでは、概念問題が解決されるまで多形ラムダを追加しないことに言及しています。なぜなら、彼らは将来も概念に似た機能を求めているからです。 –

+0

笑何政治家。 :)それでは、答えから外してください。 – wilhelmtell

0

あなたはセットを繰り返し処理できるはずです。ただし、セット内の要素もそのキーであるため、変更することはできません。 constの参照を取るようにコードを変更し、要素を変更しない場合は、セットかどうかにかかわらず、代わりにcbegin/cendを使用してください。

1

逆参照されたset<int>イテレータは、const int&です。したがってconstのないint&パラメータとして渡すことはできません。プレーン(int i)または(const int& i)を試してください。

これは実際にあなたが使用できる場所の1つではありませんauto。私はautoは、イニシャライザを使った宣言や後続の戻り型のプレースホルダとしてしか機能しないと思います。

3

ボーナスに関する質問:「自動」関数の引数は、ラムダに固有のものではありません。 すべて関数をf(auto x, auto y)と宣言することを許可しない理由を尋ねるかもしれません。しかし、それは基本的にすべての関数を関数テンプレートで置き換えることを意味します。これは、既存のC++言語や型システムではうまく機能しないと考えられていました。関数テンプレートが必要な場合は、すでに既存の構文とメカニズムがあり、 "auto"引数を宣言するのは方法ではありません。

関連する問題