In the following, one way of initialising a member is accepted and the other is an error. I don't understand:
template <typename T>
struct LambdaHolder
{
LambdaHolder(T lambdaIn) { lambda = lambdaIn; } // This will not work
LambdaHolder(T lambdaIn) : lambda(lambdaIn) { } // This will work fine
T lambda;
};
int main()
{
auto lambda = []() { return 0; };
LambdaHolder<decltype(lambda) > foo(lambda); // This will work only if the constructor argument is assigned in the initialiser list
// On the other hand
int(*lambdaPtr)() = lambda; // A function pointer
LambdaHolder<decltype(lambdaPtr)> foo(lambdaPtr); // Will work either in initialiser list or constructor body
}
I'm not understanding a couple of things. I know that certain members must be initialised in the member initialiser list, like references and const members. What I don't understand is why it will let me copy the lambda in the initialiser list but not in the constructor body. The error is "you cannot construct a copy of a lambda".
Also, I was able to create a pointer to the lambda, and initialising the pointer in either the initialiser list or the constructor body worked. Now, I know that lambdas and function pointers aren't exactly the same type, but the thing is that I thought that a captureless lambda is implemented as a free function, which is why you can set a normal function pointer to it, and also thought that when passing as an argument it would definitely decay to a pointer.
Basically I would like some clarification this, what's the difference for the distinction between initialising in the constructor body or initialiser list?
Edit: It seems, as Whoan has pointed out, that a lambda's default constructor's deleted before C++14, and non-existent after C++14 I think.