理解匿名仿函数和 lambda
Understanding anonymous-functors and lambda
考虑以下代码:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> srcVec;
for (int val = 0; val < 10; val++)
{
srcVec.push_back(val);
}
std::for_each(srcVec.begin(), srcVec.end(), [](int a){ std::cout << a << std::endl; });
}
我认为 Function
类型
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
应该有必要超载operator ()
。但是 N4296::5.1.2/3 [expr.prim.lambda]
不需要那样做。
The closure type is declared in the smallest block scope, class scope,
or namespace scope that contains the corresponding lambda-expression.
An implementation may define the closure type differently from what is
described below provided this does not alter the observable behavior
of the program other than by changing:
(3.1) — the size and/or alignment of the closure type,
(3.2) — whether the closure type is trivially copyable (Clause 9),
(3.3) — whether the closure type is a standard-layout class (Clause
9), or
(3.4) — whether the closure type is a POD class (Clause 9).
没有提到类型应该重载 operator ()
。那为什么要这样做呢?
这在第 5
段中有介绍(强调我的):
The closure type for a non-generic lambda-expression has a public inline function call operator (13.5.4)
whose parameters and return type are described by the lambda-expression’s parameter-declaration-clause
and trailing-return-type respectively. For a generic lambda, the closure type has a public inline function call
operator member template (14.5.2) whose template-parameter-list consists of one invented type templateparameter
for each occurrence of auto in the lambda’s parameter-declaration-clause, in order of appearance.
The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares
a function parameter pack (8.3.5). The return type and function parameters of the function call
operator template are derived from the lambda-expression’s trailing-return-type and parameter-declarationclause
by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with
the name of the corresponding invented template-parameter
我们可以在 13.5.4
中看到:
operator() shall be a non-static member function with an arbitrary number of parameters[...]
考虑以下代码:
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> srcVec;
for (int val = 0; val < 10; val++)
{
srcVec.push_back(val);
}
std::for_each(srcVec.begin(), srcVec.end(), [](int a){ std::cout << a << std::endl; });
}
我认为 Function
类型
template<class InputIterator, class Function>
Function for_each(InputIterator first, InputIterator last, Function f);
应该有必要超载operator ()
。但是 N4296::5.1.2/3 [expr.prim.lambda]
不需要那样做。
The closure type is declared in the smallest block scope, class scope, or namespace scope that contains the corresponding lambda-expression. An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing:
(3.1) — the size and/or alignment of the closure type,
(3.2) — whether the closure type is trivially copyable (Clause 9),
(3.3) — whether the closure type is a standard-layout class (Clause 9), or
(3.4) — whether the closure type is a POD class (Clause 9).
没有提到类型应该重载 operator ()
。那为什么要这样做呢?
这在第 5
段中有介绍(强调我的):
The closure type for a non-generic lambda-expression has a public inline function call operator (13.5.4) whose parameters and return type are described by the lambda-expression’s parameter-declaration-clause and trailing-return-type respectively. For a generic lambda, the closure type has a public inline function call operator member template (14.5.2) whose template-parameter-list consists of one invented type templateparameter for each occurrence of auto in the lambda’s parameter-declaration-clause, in order of appearance. The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares a function parameter pack (8.3.5). The return type and function parameters of the function call operator template are derived from the lambda-expression’s trailing-return-type and parameter-declarationclause by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with the name of the corresponding invented template-parameter
我们可以在 13.5.4
中看到:
operator() shall be a non-static member function with an arbitrary number of parameters[...]