我希望得到lambda的类型作为模板参数。怎么做?
template<class T>
class Foo
{
public:
Foo(T t){ t(); }
};
int main()
{
Foo< type?? > foo([](){ cout<<"construct OK"; });
system("pause");
return 0;
}
答案 0 :(得分:10)
当它是推导出类型的函数模板函数参数的参数时,可以推导出lambda表达式的类型。
然而,明确禁止Lambda表达式出现在未评估的操作数内 - 这包括decltype
。结果发现,这包括几个尚未处理的特殊情况,并且发现在decltype
和朋友中允许lambda表达没有实际效用。回想一下,每个lambda表达式都会创建一个新的唯一类型。
您可以改为使用std::function<void()>
,它可以存储任何可以不带参数调用的函数对象,并将void
作为返回类型。
Foo< std::function<void()> > foo([](){ cout<<"construct OK"; });
当然,正如我上面所说,函数模板可以推导出它们的参数类型,因此你也可以使构造函数成为模板
class Foo
{
public:
template<typename T>
Foo(T t){ t(); }
};
Foo foo([](){ cout<<"construct OK"; });
但是我认为这在你的情况下并不是很有用,因为你可能想在你的类定义中使用T
做一些事情。比如,将对象存储为非静态数据成员。使用std::function
,这是可能的。
答案 1 :(得分:1)
仍然采用传统方式使用函数来推断类型:
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"; });
但我想支持lambda的编译器通常也支持decltype
和auto
,因此Matteo的答案可能更好。