在lambda函数中使用auto

#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不应该用在lambdaexpression式中?

这工作:

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

为什么使用auto关键字的版本不起作用?

auto关键字不能用作函数参数的types。 如果你不想在lambda函数中使用实际的types,那么你可以使用下面的代码。

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

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 ++types系统中非常不同的一种实体(思考所有模板的特殊规则,比如两阶段查找和推演),这将是一个彻底的devise变革,带来不可预见的后果,很快就会在标准中出现。

C ++ 14允许使用auto声明lambda函数(通用lambda函数)参数。

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

详情请见http://en.cppreference.com/w/cpp/language/lambda

在编译器甚至可以实例化std::for_each之前,需要知道lambda的types。 另一方面,即使理论上可能,只有在函数被调用的情况下, for_each被实例化之后,才能推导出该auto

如果可能的话,忘记for_each ,并使用基于范围的for循环更简单:

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

这也应该很好地处理auto (和auto&const auto& )。

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