C++ 在 lambda 函数中使用 auto
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7709894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using auto in a lambda function
提问by B?ови?
#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?
这是否意味着auto
不应在 lambda 表达式中使用关键字?
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 关键字的版本不起作用?
回答by Jagannath
auto keyword does not work as a type for function arguments, in C++11. If you don't want to use the actual type in lambda functions, then you could use the code below.
在 C++11 中,auto 关键字不能用作函数参数的类型。如果您不想在 lambda 函数中使用实际类型,则可以使用下面的代码。
for_each(begin(v), end(v), [](decltype(*begin(v)) it ){
foo( it + 5);
});
The code in the question works just fine in C++ 14.
问题中的代码在 C++ 14 中工作得很好。
回答by Razan Paul
C++14 allows lambda function (Generic lambda function) parameters to be declared with the auto.
C++14 允许使用 auto 声明 lambda 函数(通用 lambda 函数)参数。
auto multiply = [](auto a, auto b) {return a*b;};
For details: http://en.cppreference.com/w/cpp/language/lambda
回答by Kerrek SB
This was discussed briefly by Herb Sutter during an interview. Your demand for auto
arguments is in fact no different from demanding that anyfunction should be declarable with auto
, like this:
Herb Sutter 在接受采访时简要讨论了这一点。你对auto
参数的要求实际上与要求任何函数都应该用 声明没有什么不同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 templatefunction, 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++ 类型系统中的一种非常不同的实体(想想模板的所有特殊规则,例如两阶段查找和推导),这将是具有不可预见后果的激进设计更改,这当然不是'不会很快达到标准。
回答by visitor
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.
在编译器甚至可以实例化之前,需要知道 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_each
,并使用更简单的基于范围的 for 循环:
for (int it : v) {
foo(it + 5);
}
This should also cope nicely with auto
(and auto&
and const auto&
).
这也应该很好地应对auto
(andauto&
和const auto&
)。
for (auto it : v) {
foo(it + 5);
}