我正在编写一个模板函数,它将一个函数对象(现在是一个lambda)作为参数,使用lambda数据类型作为模板参数,并返回lambda返回的相同类型。像这样:
template<typename TFunctor, typename TReturn>
TReturn MyFunc(TFunctor &Func, TReturn) //The second arg is just to keep the template spec happy
{
return Func();
}
消费代码如下:
int n = MyFunc([](){return 17;}, int());
我不喜欢指定返回数据类型的丑陋方式。在编译器生成的lambda类中是否有一些内置的typedef会给我它的返回类型?所以MyFunc可以这样做:
template<typename TFunctor>
TFunctor::return_type MyFunc(TFunctor &Func)
{ //...
我希望它返回lambda返回的相同类型,而不显式地拼写出该类型。
编辑:现在,我所关心的所有lambda都没有争议。变量捕获也可以做到这一点。答案 0 :(得分:6)
由于返回类型可以取决于赋予仿函数的参数,因此需要在某处指定它们以查询返回类型。因此,在谈到泛型仿函数(不将它们限制为(非泛型)lambdas时),当不知道参数的类型时,不可能确定返回类型。
C ++ 11具有关键字decltype
,可以与尾随返回类型结合使用,以便通过命名一个可以依赖的表达式来指定函数的返回类型关于函数参数(这里,它取决于Func
是什么):
template<typename TFunctor>
auto MyFunc(TFunctor &Func) -> decltype(Func(/* some arguments */))
{ ... }
因此,如果您以无参数的方式调用它(我在查看您的lambda示例时假设这一点),只需写:
template<typename TFunctor>
auto MyFunc(TFunctor &Func) -> decltype(Func())
{
return Func();
}
在C ++ 14中,您甚至可以完全省略返回类型,只需编写
即可template<typename TFunctor>
auto MyFunc(TFunctor &Func)
{
return Func();
}
请注意,即使在C ++ 03中,您也不必提供另一个函数参数;另一个模板参数就足够了:
template<typename TReturn, typename TFunctor>
TReturn MyFunc(TFunctor &Func)
{
return Func();
}
int n = MyFunc<int>(someFunctorReturningAnInt);