【问题标题】:How to create a type with expanded argument list of template<typename... Args> function?如何使用模板<typename... Args> 函数的扩展参数列表创建类型?
【发布时间】:2021-07-15 09:26:34
【问题描述】:

一般来说,我不知道如何创建这样的类型:

template<typename... Args>
using TWrapper = void *(*)(void *target, Args... func_args);

我明白为什么这会引发错误,但我不知道该怎么办......

我正在开发一个内容如下的课程:

template<typename TFunc> //TFunc is a type of user's function
class CallManager {
    TFunc user_function = nullptr;
    void* inner_state; //For example

    template<typename... Args>
    using TWrapper = void *(CallManager::*)(void *const target, Args... func_args);

    TWrapper wrapper_from_another_instance = nullptr; //What do I need to specify in the template arguments if I don't know them?

    template <typename... Args> //I need to create a type for this function
    void* WrapUserFunction(void *const target, Args&&... func_args) {
        user_function(std::forward<Args>(func_args)...);
    }

    void setTargetExecutor(TWrapper wrapper) {
        wrapper_from_another_instance = wrapper;
    }
public:
    void setFunction(TFunc func) {
        user_function = func;
    }

    template <typename... Args>
    void makeCall(Args&&... func_args) {
        wrapper_from_another_instance(inner_state, std::forward<Args>(func_args)...);
    }

    void bindManager(const CallManager &next) { //Upd 1
        setTargetExecutor(next.WrapUserFunction);
    }
};

使用上述类的示例,可能会注意到我需要一个“扩展”类型,以便为它创建一个指向函数的变量指针,然后调用它。

我的类接受自定义函数类型,但我不知道有多少参数以及它们是什么类型。是否有可能以某种方式提取参数列表?

如何为以“template”开头的函数创建类型?

如何用我自己的参数补充用户的类型以将结果保存在变量中以供调用?

UPD 1:使用示例

using myfunc = void(*)(char x, char y);

void myFunc(char x, char y) {
}

void main() {
    CallManager<myfunc> cmgr1;
    cmgr1.setFunction(myFunc);

    CallManager<myfunc> cmgr2;
    cmgr2.bindManager(cmgr1);

    cmgr2.makeCall(10, 15);
}

【问题讨论】:

  • 能否请您添加该类的示例用法?
  • @KamilCuk 重点是我正在围绕 C 接口编写一个包装器。以上部分是处理创建和处理调用的类的摘录。在 C-lib 中,有关自定义类型的所有内容都由用户处理(C-api 到处使用void *),但在 C++ 中,这是不好的风格。为这个示例编写有意义的用法可能并不容易,但我会尝试。
  • 这似乎是一个很奇怪的界面。为什么恰好有两个CallManager 实例来调用该函数?
  • @Caleth 我只是举了一个例子。真正的类实现了其他功能:在不同的程序模块中使用管理器,第一个管理器调用第二个管理器,依此类推,每个管理器都有决定是继续调用还是中断调用的钩子。这个类相当大,所以我创建了一个纯粹为了这个问题的例子。

标签: c++ types function-pointers variadic-functions c++20


【解决方案1】:

如果你限制你的类使用函数指针,你可以这样做:

template<typename TFunc> //TFunc is a type of user's function
class CallManager;

template<typename R, typename... Args>
class CallManager<R (*)(Args...)>
{
    using TFunc = R (*)(Args...);
    using TWrapper = void *(CallManager::*)(void *const, Args...);
// ...
};

如果你需要支持更多的可调用类型,我建议创建一个“function_traits”在相同的原则(template specialization)作为助手。

Demo/Demo2

【讨论】:

  • 是否可以将模板参数的数量减少到一个(例如函数类)?例如,我想这可以通过std::function 来完成,但是我该如何获取类型呢?
  • 为什么在声明类时模板会初始化?此行:class CallManager&lt;R (*)(Args...)&gt;
  • 模板参数只有一个CallManager&lt;void (*)(int, char)&gt;(主要是std::function&lt;void(int, char)&gt;,你甚至可以从声明中删除指针)。
  • Demos 已添加。
  • @AlexA.:您的样本有几个错误,忽略了Args... 主要问题。第一个演示(在您的示例使用之前创建)使用方法指针,缺少要应用的实例;我使用this。其次,inner_state似乎是实例,所以要么应该在参数或常规函数中,要么不应该是方法的参数(我选择前者)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 2021-11-02
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多