在lambda函数中使用auto

时间:2011-10-10 07:53:47

标签: c++ c++11 auto lambda

#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

是否意味着不应在lambda表达式中使用关键字auto

这有效:

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

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

4 个答案:

答案 0 :(得分:67)

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

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

答案 1 :(得分:20)

Herb Sutter在接受采访时对此进行了简要讨论。您对auto参数的需求实际上与要求{em>任何函数应该使用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 :(得分:20)

C ++ 14允许使用auto。

声明lambda函数(Generic lambda函数)参数
auto multiply = [](auto a, auto b) {return a*b;};

详细信息:http://en.cppreference.com/w/cpp/language/lambda

答案 3 :(得分:4)

在编译器甚至可以实例化std::for_each之前,需要知道lambda的类型。另一方面,即使理论上可行,auto也只能在for_each实例化之后通过查看仿函数的调用来推断。

如果可能的话,忘记for_each,并使用基于范围的for循环,这些循环要简单得多:

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

这也应该与auto(以及auto&const auto&)很好地对应。

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