43
#include <vector>
#include <algorithm>

void foo( int )
{
}

int main()
{
  std::vector< int > v( { 1,2,3 } );

  std::for_each( v.begin(), v.end(), []( auto it ) { foo( it+5 ); } );
}

上記の例をコンパイルすると、次のようなエラー出力が開始されます。

h4.cpp: In function 'int main()':
h4.cpp:13:47: error: parameter declared 'auto'
h4.cpp: In lambda function:
h4.cpp:13:59: error: 'it' was not declared in this scope

キーワードautoをラムダ式で使用してはならないということですか?

これは機能します:

std::for_each( v.begin(), v.end(), []( int it ) { foo( it+5 ); } );

auto キーワードを含むバージョンが機能しないのはなぜですか?

4

4 に答える 4

69

C++11 では、auto キーワードが関数の引数の型として機能しません。ラムダ関数で実際の型を使用したくない場合は、以下のコードを使用できます。

 for_each(begin(v), end(v), [](decltype(*begin(v)) it ){
       foo( it + 5);         
 });

問題のコードは、C++ 14 で問題なく動作します。

于 2011-10-10T08:03:32.493 に答える
24

C++14 では、ラムダ関数 (汎用ラムダ関数) のパラメーターを auto で宣言できます。

auto multiply = [](auto a, auto b) {return a*b;};

詳細: http://en.cppreference.com/w/cpp/language/lambda

于 2015-07-15T23:30:32.983 に答える
22

これについては、インタビュー中に Herb Sutter が簡単に説明しました。auto実際、引数に対する要求は、次のように関数を で宣言できるautoようにすることと同じです。

auto add(auto a, auto b) -> decltype(a + b) { return a + b; }

ただし、これは実際には関数ではなく、次のようなテンプレート関数であることに注意してください。

template <typename S, typename T>
auto add(S a, T b) -> decltype(a + b) { return a + b; }

したがって、基本的には、引数を変更して任意の関数をテンプレートに変換する機能を求めています。テンプレートは C++ の型システムでは非常に異なる種類のエンティティであるため (2 フェーズのルックアップや推論など、テンプレートのすべての特別な規則を考えてみてください)、これは予期できない影響を伴う抜本的な設計変更になります。 t は、すぐに標準になる予定です。

于 2011-10-10T10:16:15.857 に答える
4

ラムダの型は、コンパイラがインスタンス化する前に知る必要がありますstd::for_each。一方、理論的には可能であったとしても、それはファンクターがどのように呼び出されるかを見てインスタンス化さautoれた後でしか推測できませんでした。for_each

可能であれば、 を忘れてfor_each、より単純な範囲ベースの for ループを使用します。

for (int it : v) { 
   foo(it + 5); 
}

autoこれは(and auto&and )にもうまく対応するはずconst auto&です。

for (auto it : v) { 
   foo(it + 5); 
}
于 2011-10-10T09:43:22.903 に答える