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不应该在 lambda 表达式中使用?

这有效:

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

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

4

4 回答 4

69

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

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

问题中的代码在 C++ 14 中运行良好。

于 2011-10-10T08:03:32.493 回答
24

C++14 allows lambda function (Generic lambda function) parameters to be declared with the auto.

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

For details: http://en.cppreference.com/w/cpp/language/lambda

于 2015-07-15T23:30:32.983 回答
22

This was discussed briefly by Herb Sutter during an interview. Your demand for auto arguments is in fact no different from demanding that any function should be declarable with auto, like this:

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

However, note that this isn't really a function at all, but rather it's a template function, akin to:

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

So you are essentially asking for a facility to turn any function into a template by changing its arguments. Since templates are a very different sort of entity in the type system of C++ (think of all the special rules for templates, like two-phase look-up and deduction), this would be radical design change with unforeseeable ramifications, which certainly isn't going to be in the standard any time soon.

于 2011-10-10T10:16:15.857 回答
4

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

If at all possible, forget about for_each, and use range-based for loops which are a lot simpler:

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

This should also cope nicely with auto (and auto& and const auto&).

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