简体   繁体   English

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

[英]Get type of function first parameter for template function return type

I have the following template function: 我具有以下模板功能:

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

It's expected to be used with F with the form 预期与F一起使用,格式为

void some_function(SomeType& s);

in this way 通过这种方式

function<SomeType>(some_function);

The first template argument seems redundant because can be deduced from the parameters of the parameter function. 第一个模板参数似乎是多余的,因为可以从参数函数的参数中得出。 The question is Exists a way to get rid of the first template parameter? 问题是存在一种摆脱第一个模板参数的方法吗?

Something like 就像是

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

So that I can use it as 这样我就可以将其用作

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

solves the problem as stated. 解决了上述问题。 The general problem cannot be solved (where F is an arbitrary callable), as callables in C++ can accept more than one type, and deducing what types are acceptable cannot be solved in the general case. 一般问题无法解决(其中F是任意可调用的对象),因为C ++中的可调用对象可以接受不止一种类型,并且在一般情况下无法推论哪些类型可以接受。

If you had a list of types you support, it an be solved in general. 如果您有支持的类型列表,则通常可以解决。

The basic problem in C++14 is function([](auto&x){ std::cout << x << '\\n'; }) . C ++ 14中的基本问题是function([](auto&x){ std::cout << x << '\\n'; }) The same problem exists in C++11 with function objects with a template operator() . 在C ++ 11中,带有模板operator()函数对象也存在相同的问题。 The fact that auto-lambdas are supported in C++14 means that such objects are going to become more and more common in the future. C ++ 14支持自动lambda的事实意味着将来此类对象将变得越来越普遍。

Consider changing your design so that the signature of your F is T() rather than void(T&) . 考虑更改设计,使F的签名为T()而不是void(T&) Then we get: 然后我们得到:

template<class F>
std::result_of_t<F()>
function( F&& f ) {
  ...
  return std::forward<F>(f)();
}

or typename std::result_of<F()>::type in C++11. 或C ++ 11中的typename std::result_of<F()>::type

I hope I understood your question, maybe I am wrong... 希望我理解您的问题,也许我错了...

First of all I expect your template function must be called and for the call it needs additional parameters which I could not found in your example code. 首先,我希望必须调用您的模板函数,并且该调用需要其他示例参数中找不到的其他参数。

But ok, what I expect what you can do: 但是好吧,我期望您能做什么:

#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;
}   

As you already mentioned, there is no need to give the return type as additional parameter, because it can be found in the given as type in the presented function pointer to the template. 正如您已经提到的,不需要将返回类型作为附加参数,因为可以在提供给模板的函数指针中以给定类型找到返回类型。

The wrapper template will work for all return types but not for void ! 包装器模板将适用于所有返回类型,但不适用于void

UPDATE 更新

I absolutely agree with Yakk's answer I just wanted to mention an other but very similar way: 我完全同意Yakk的回答,我只想提及另一种但非常相似的方式:

#include <functional>

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM