#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关键字的版本不起作用?
答案 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;};
答案 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);
}