Why does the first call not compile?
auto get1 = []() { return B; };
auto get2 = [](B b) { return b; };
int main()
{
get1
This is easier to understand if you consider what the equivalent class type looks like to your get1
:
struct get1_t {
template <int B> operator()() const { return B; }
};
get1_t get1;
get1<5>(); // error
You're trying to provide an explicit template parameter to the call operator, but syntactically you're doing what looks like providing template parameters for get1
itself (i.e. as if get1
were a variable template). In order to provide the template parameter for the call operator, you have to do that directly:
get1.operator()<5>(); // ok
Or restructure the call operator to take something deducible:
template <int B> struct constant { };
get1(constant<5>{});
Or restructure the whole thing to actually be the variable template that it looks like it is:
template <int B>
auto get1 = [] { return B; };
Now, get1<5>
is itself a lambda, that you're invoking. That is, rather than a lambda with a call operator template we have a variable template lambda that is itself not a template.