您可以从模板参数功能签名中提取类型吗? [英] Can you extract types from template parameter function signature

查看:57
本文介绍了您可以从模板参数功能签名中提取类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以以 foo(bar)的形式从函数签名中提取类型,并仅访问 foo bar 。因此,如果我有模板:

Is there a way that I can extract the types from a function signature in the form foo(bar) and get access to just foo or bar. So if I have the template:

template<typename signiture>
class type{
};

其中签名为 foo(bar)然后在类中有一个读取以下内容的函数

where signiture is foo(bar) and then have a function in the class that reads

foo function(bar b){
    //do stuff
}

我正在与 std :: function ,并且发现使用 foo(bar)语法比使用多个模板参数更方便:

I am interfacing with std::function and have found it more convenient to use the foo(bar) syntax instead of using multiple template params like so:

template<typename return_t,param_tps... args>
class type{
    return_t function(param_ps args...){
        return something;
    }
};

让我知道是否可以澄清一下吗?
提前致谢。

Let me know if i can clarify please? Thanks in Advance.

编辑:
用于说明我对具有N个参数的函数感兴趣,该参数由特定类决定实例指定。

for clarification i am interested in a function with N number of parameters to be determined by whatever the specific class instance specifies.

编辑2:
该问题所基于的代码如下:

EDIT 2: The code that this question is based off of is as follows:

using std::function;
template <typename signiture>
class Observer;

template <typename return_t, typename ...args_t>
class Observer<return_t(args_t...)> {
protected:
    using signature = return_t(args_t...);
    typedef function<signature> func_t;
    ~Observer(){}
    func_t what_to_do;
public:
    Observer(Subject<signature>& subject,func_t what):what_to_do(what){
        subject.Attach(what_to_do);
    }
    return_t operator()(args_t... args){
        what_to_do(args...);
    }
};

using std::function;
using std::vector;
template <typename signature>
class Subject;

template <typename return_t,typename...param_tps>
class Subject<return_t(param_tps...)> {
    using signature=return_t(param_tps...);
public:
    void Attach(std::function<signature> o){
        obs.push_back(o);
    }
    void operator()(param_tps... params){
        for (typename vector<std::function<signature>>::const_iterator i=obs.begin(); i!=obs.end(); ++i) {
            (*i)(params...);
        }
    }
protected:
    ~Subject(){}
    vector<std::function<signature>> obs;

};

这是Observer模式的实现,使用 std是非虚拟的:: function 将两者粘合在一起。我想使用 foo(bar)语法,因为它更有利于类的易用性。问题是将函数类型签名转换为返回类型和参数类型,以便在主题类中指定正确的 operator(),以便它可以通过以下方式通知观察者:正确的数据。

It is an implementation of the Observer pattern that is non-virtual using std::function to glue things together between the two. I wanted to use the foo(bar) syntax because everything it is more conducive to the ease of use of the classes. The issue was converting the function type signature into the return type and the parameter types in order to specify the proper operator() in the subject class so that it can notify the observers with the correct data.

所做的更改基于以下示例:

The changes that were made were based upon the example given below as follows:

template<typename t>struct type;
template<typename R,typename... args_t>
struct type<R(args_t...)>{
//use R and args_t as needed
}

感谢所有提供帮助的人。

Thanks to all who helped.

推荐答案

这是一个非常基本的解决方案适用于接受一个参数的函数(似乎您在问题中放置了此约束,但是很容易提供一个通用的解决方案,如下所示):

Here is a very basic solution that works for functions accepting one parameter( it seems you are placing this constraint in the question, but a generalized solution is quite easy to provide, as shown in the following):

template<typename S>
struct type; // You can leave this undefined, because the template is
             // supposed to be instantiated with a function type, and
             // that is matched by the specialization below.

template<typename R, typename Arg>
struct type<R(Arg)>
{
    // Just use R and Args as you wish here..
};

以下是一个可能的示例( Coliru上的实时演示):

Here is a possible example (live demo on Coliru):

#include <type_traits>

template<typename S>
struct signature;

template<typename R, typename Arg>
struct signature<R(Arg)>
{
    using return_type = R;
    using argument_type = Arg;
};

int main()
{
    using ret = signature<void(int)>::return_type;
    using arg = signature<void(int)>::argument_type;

    static_assert(std::is_same<ret, void>{}, "!");
    static_assert(std::is_same<arg, int>{}, "!");
}

如果您对可变参数的通用解决方案感兴趣,

In case you are interested in a more general solution for the variadic case, this is probably what you're looking for:

#include <tuple>

struct type; // You can leave this undefined, because the template is
             // supposed to be instantiated with a function type, and
             // that is matched by the specialization below.

template<typename R, typename... Args>
struct type<R(Args...)>
{
    // Just use R and Args... as you with here..
};

这是一个可能的用法示例( Coliru上的实时演示):

And here is a possible usage example (live demo on Coliru):

#include <tuple>
#include <type_traits>

template<typename S>
struct signature;

template<typename R, typename... Args>
struct signature<R(Args...)>
{
    using return_type = R;
    using argument_type = std::tuple<Args...>;
};

int main()
{
    using ret = signature<void(int, double)>::return_type;
    using arg1 = std::tuple_element_t<0, signature<void(int, double)>::argument_type>;
    using arg2 = std::tuple_element_t<1, signature<void(int, double)>::argument_type>;

    static_assert(std::is_same<ret, void>{}, "!");
    static_assert(std::is_same<arg1, int>{}, "!");
    static_assert(std::is_same<arg2, double>{}, "!");
}

这篇关于您可以从模板参数功能签名中提取类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆