在lambda函数中使用auto

时间:2022-08-03 18:02:05
#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?

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

This works :

如此:

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

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

为什么带有auto关键字的版本不能工作?

4 个解决方案

#1


64  

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.

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

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

#2


19  

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:

赫伯·萨特(Herb Sutter)在一次采访中简要地讨论了这一点。您对自动参数的要求实际上与要求任何函数都可以用auto进行声明没有什么不同,如下所示:

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.

本质上,你要求一个工具通过改变参数将任何函数转换成模板。由于模板在c++的类型系统中是一种非常不同的实体(考虑到所有模板的特殊规则,比如两阶段查找和演绎),这将是一种具有不可预见后果的根本性设计变更,这肯定不会很快出现在标准中。

#3


19  

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

c++ 14允许lambda函数(泛型lambda函数)参数与auto一起声明。

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

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

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

#4


4  

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.

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

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

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

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

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

这也可以很好地处理auto(和auto&const auto&)。

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

#1


64  

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.

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

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

#2


19  

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:

赫伯·萨特(Herb Sutter)在一次采访中简要地讨论了这一点。您对自动参数的要求实际上与要求任何函数都可以用auto进行声明没有什么不同,如下所示:

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.

本质上,你要求一个工具通过改变参数将任何函数转换成模板。由于模板在c++的类型系统中是一种非常不同的实体(考虑到所有模板的特殊规则,比如两阶段查找和演绎),这将是一种具有不可预见后果的根本性设计变更,这肯定不会很快出现在标准中。

#3


19  

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

c++ 14允许lambda函数(泛型lambda函数)参数与auto一起声明。

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

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

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

#4


4  

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.

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

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

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

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

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

这也可以很好地处理auto(和auto&const auto&)。

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