In program as follows function template f
having two arguments declares the type of the second argument by using decltype
with lambda expression inside referring to the first function’s argument p
(here for illustration purposes it just removes the reference from the type):
int f( auto && p,
decltype([p](){return p;}()) ) //#1
{ return 0; }
int main() {
int i = 0;
return f( i, 0 );
}
Unfortunately, GCC rejects it with the error:
error: use of parameter outside function body before ‘;’ token
MSVC:
error C3536: ‘p’: cannot be used before it is initialized
Clang’s error is less clear:
error: variable ‘p’ cannot be implicitly captured in a lambda with no capture-default specified
Online demo: https://gcc.godbolt.org/z/oeWMb6ozo
Now if one uses an initializer for lambda capture:
int f( auto && p,
decltype([p=p](){return p;}()) ) //#2
{ return 0; }
the behavior of compilers does change.
MSVC:
error C2853: ‘p’: a non-static data member cannot have a type that contains ‘auto’
Clang simply crashes.
But GCC accepts program #2 just fine. Online demo: https://gcc.godbolt.org/z/ebco5cYsh
Is program #2 really well-formed and #1 not? What are the limitations on using function template arguments for defining types of other arguments?