9

Why does the first call not compile?

auto get1 = []<int B>() { return B; };
auto get2 = []<typename B>(B b) { return b; };

int main()
{
    get1<5>(); // error: no match for operator<
    get2(5);   // ok
}

The reason I use this, is an expression repeated many times in code.

Of course I can use a real function template, but just I am curious WHY.

1 Answer 1

11

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.

Sign up to request clarification or add additional context in comments.

1 Comment

@Bergi It's the same kind of thing as get1<5>()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.