获取模板函数返回类型的函数类型第一个参数

时间:2015-05-07 17:45:15

标签: c++ templates c++11

我有以下模板功能:

template<class T, class F> T function(F& f) {
        ...
        T t; 
        f(t);
        return t;
}

预计将与F一起使用,格式为

void some_function(SomeType& s);

以这种方式

function<SomeType>(some_function);

第一个模板参数似乎是多余的,因为可以从参数函数的参数中推断出来。 问题是 是否存在摆脱第一个模板参数的方法?

这样的东西
template<class F> first_param_type<F> function(F& f) {
        ...
        first_param_type<F> t; 
        f(t);
        return t;
}

因此我可以将其用作

function(some_function);

3 个答案:

答案 0 :(得分:3)

template<class T>
T function( void(*f)(T&) ) {
  ...
  T t; 
  f(t);
  return t;
}

解决了所述的问题。一般问题无法解决(F是任意可调用的),因为C ++中的callable可以接受多种类型,并且在一般情况下无法解决可接受的类型。

如果你有一个你支持的类型列表,那么通常可以解决它。

C ++ 14中的基本问题是function([](auto&x){ std::cout << x << '\n'; })。 C ++ 11中存在同样的问题,其中函数对象具有模板operator()。 C ++ 14支持自动lambda这一事实意味着这些对象将来会变得越来越普遍。

请考虑更改您的设计,以使F的签名为T()而不是void(T&)。然后我们得到:

template<class F>
std::result_of_t<F()>
function( F&& f ) {
  ...
  return std::forward<F>(f)();
}
C ++ 11中的

typename std::result_of<F()>::type

答案 1 :(得分:0)

我希望我理解你的问题,也许我错了......

首先,我希望你的模板函数必须被调用,而对于调用,它需要我在示例代码中找不到的其他参数。

但是,我希望你能做些什么:

#include <iostream>
using namespace std;

template <typename RetType, typename ... Parms>
auto TemplateFunction  ( RetType(*ptr)(Parms ...), Parms ... parms ) -> RetType
{   
    RetType ret;
    ret = (*ptr)( parms...);
    cout << "Value ret in Wrapper is:" << ret << endl;
    return ret;
}   

double AnyFunc(int a, int b) { return 3.14 * a + b; }
std::string OtherFunc(  ) { return "Hallo"; } 

int main()
{   
    double result = TemplateFunction(&AnyFunc, 1,3);

    cout << "Result is " << result << endl;

    cout << TemplateFunction(&OtherFunc) << endl;
}   

正如您已经提到的,不需要将返回类型作为附加参数,因为它可以在给定的函数指针中的给定类型中找到。

包装器模板适用于所有返回类型,但不适用于void

答案 2 :(得分:0)

更新

我绝对同意Yakk的回答我只是想提一下其他但非常相似的方式:

#include <functional>

template < class Type >
Type myFunction( const std::function< void( Type& ) >& aFunction )
{
    Type instance;
    aFunction( instance );
    return instance;
}