I want get the type of lambda as the template argument. How to do this?
template<class T>
class Foo
{
public:
Foo(T t){ t(); }
};
int main()
{
Foo< type?? > foo([](){ cout<<"construct OK"; });
system("pause");
return 0;
}
It's possible to deduce the type of a lambda-expression when it is the argument to a function template function parameter whose type is deduced.
Lambda expressions however are explicitly forbidden to appear inside an unevaluated operand --- this includes decltype
. It was found that this includes several yet unhandled special cases and it was found that there is no real utility to allow lambda expressions inside decltype
and friends. Recall that every lambda expression creates a new unique type.
You can instead use std::function<void()>
, which is able to store any function object that can be called without arguments and yields void
as return type.
Foo< std::function<void()> > foo([](){ cout<<"construct OK"; });
Of course, as I said above, function templates can deduce their argument type, so you can also make the constructor a template
class Foo
{
public:
template<typename T>
Foo(T t){ t(); }
};
Foo foo([](){ cout<<"construct OK"; });
But I take it that this is not really useful in your case, since you presumably want to do something with T
inside your class definition. Like, storing the object as a non-static data member. With std::function
, that's possible.
There is still the old-fashioned way of using functions to deduce types:
template<class T>
class Foo
{
public:
Foo(T t){ t(); }
};
template <typename T>
Foo<T> make_foo(T const& t)
{
return Foo<T>(t);
}
... make_foo([](){ cout<<"construct OK"; });
but I guess compilers that support lambdas usually support decltype
and auto
as well, therefore Matteo's answer is probably better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With