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