Using auto in a lambda function

2019-01-22 05:55发布

#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 ); } );
}

When compiled, the example above starts the error output like this :

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

Does it mean that the keyword auto should not be used in lambda expressions?

This works :

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

Why the version with the auto keyword doesn't work?

4条回答
Fickle 薄情
2楼-- · 2019-01-22 06:12

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.

查看更多
够拽才男人
3楼-- · 2019-01-22 06:17

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

查看更多
戒情不戒烟
4楼-- · 2019-01-22 06:26

auto keyword does not work as a type for function arguments. If you don't want to use the actual type in lambda functions, then you could use the code below.

 for_each(begin(v), end(v), [](decltype(*begin(v)) it ){
       foo( it + 5);         
 });
查看更多
Evening l夕情丶
5楼-- · 2019-01-22 06:32

The type of the lambda needs to be known before the compiler can even instantiate std::for_each. On the other hand, even if it were theoretically possible, that auto could only be deduced after for_each has been instantiated by seeing how the functor is invoked.

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); 
}
查看更多
登录 后发表回答