K
Size: a a a
CD
КП
КП
O
operator()
, но позволяет вызвать шаблонный (очевидно, это следствие того, как реализован оператор каста к указателю на функцию). Clang же не позволяет вызвать ни тот, ни другой>> The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type
>> The closure type for a lambda-expression has a public inline function call operator (for a non-generic lambda) or function call operator template (for a generic lambda)
>> 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
— ...
(
http://eel.is/c++draft/expr.prim.lambda#closure-1 )
Ни в последнем процитированном пункте, ни во всём разделе, я не нашёл никаких исключений, касающихся name lookup
для лямбд без захвата, т.е. поиск имён в лямбде должен соответствовать поиску имён внутри unnamed non-union class type
, а значит, можно предположить, что в следующем куске кода поведение при вызове f(3)
и l(3)
должно быть эквивалентно:struct /* unnamed */ {
template<typename Auto>
constexpr int operator()(Auto n) const {
if (n <= 1) return 1;
else return n * operator()(n-1);
}
} f;
void foo() {
constexpr auto l = [](auto n) -> int {
if (n <= 1) return 1;
else return n * operator()(n-1);
};
static_assert(l(3) == f(3));
};
При этом, кажется, при нешаблонном operator()
и GCC, и MSVC оба могут быть правы, допускаю даже, что могут быть правы одновременно. Но я не вижу ни одного аргумента в пользу Clang, который не позволяет вызвать шаблонный operator()
вообщеAF
operator()
, но позволяет вызвать шаблонный (очевидно, это следствие того, как реализован оператор каста к указателю на функцию). Clang же не позволяет вызвать ни тот, ни другой>> The type of a lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type, called the closure type
>> The closure type for a lambda-expression has a public inline function call operator (for a non-generic lambda) or function call operator template (for a generic lambda)
>> 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
— ...
(
http://eel.is/c++draft/expr.prim.lambda#closure-1 )
Ни в последнем процитированном пункте, ни во всём разделе, я не нашёл никаких исключений, касающихся name lookup
для лямбд без захвата, т.е. поиск имён в лямбде должен соответствовать поиску имён внутри unnamed non-union class type
, а значит, можно предположить, что в следующем куске кода поведение при вызове f(3)
и l(3)
должно быть эквивалентно:struct /* unnamed */ {
template<typename Auto>
constexpr int operator()(Auto n) const {
if (n <= 1) return 1;
else return n * operator()(n-1);
}
} f;
void foo() {
constexpr auto l = [](auto n) -> int {
if (n <= 1) return 1;
else return n * operator()(n-1);
};
static_assert(l(3) == f(3));
};
При этом, кажется, при нешаблонном operator()
и GCC, и MSVC оба могут быть правы, допускаю даже, что могут быть правы одновременно. Но я не вижу ни одного аргумента в пользу Clang, который не позволяет вызвать шаблонный operator()
вообщеAF
AF
AF
O
The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but for purposes of name lookup, determining the type and value of this and transforming id-expressions referring to non-static class members into class member access expressions using (*this) ([class.mfct.non-static]), the compound-statement is considered in the context of the lambda-expression.
Но этот пункт вместе с примером вызывает ещё больше вопросов, да и относится, похоже, только к лямбде, объявленной внутри функции-члена другого классаAF
AF
AF
O
struct S1 {— end example]
int x, y;
int operator()(int);
void f() {
[=]()->int {
return operator()(this->x + y); // equivalent to S1::operator()(this->x + (*this).y)
// this has type S1*
};
}
};
AF
The lambda-expression's compound-statement yields the function-body ([dcl.fct.def]) of the function call operator, but for purposes of name lookup, determining the type and value of this and transforming id-expressions referring to non-static class members into class member access expressions using (*this) ([class.mfct.non-static]), the compound-statement is considered in the context of the lambda-expression.
Но этот пункт вместе с примером вызывает ещё больше вопросов, да и относится, похоже, только к лямбде, объявленной внутри функции-члена другого классаAF
struct S1 {— end example]
int x, y;
int operator()(int);
void f() {
[=]()->int {
return operator()(this->x + y); // equivalent to S1::operator()(this->x + (*this).y)
// this has type S1*
};
}
};