如何获取c ++ 0x lambda表达式的类型?

时间:2011-02-21 01:41:30

标签: c++ c++11 lambda

我希望得到lambda的类型作为模板参数。怎么做?

template<class T>
class Foo
{
public:
    Foo(T t){ t(); }
};

int main()
{   
    Foo< type?? > foo([](){ cout<<"construct OK"; });

    system("pause");
    return 0;
}

2 个答案:

答案 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的编译器通常也支持decltypeauto,因此Matteo的答案可能更好。