【问题标题】:C++ Function that passes any function with any number of arguments传递具有任意数量参数的任何函数的 C++ 函数
【发布时间】:2013-03-18 13:41:09
【问题描述】:

这在 c++ 中可能是不可能的,但我在网上搜索并没有发现任何似乎有效的东西。

我不知道这是如何工作的,但是如果我将函数“A”传递给另一个函数“B”,我可以像这样在“A”中执行函数“B”:

template<typename Func>
void process(Func func) {
    func();
}

void myVoidFunction() {
    cout << "I did something!?" << endl;
}

process(myVoidFunction); // This will run myVoidFunction();

现在,我不知道如何对具有任意数量参数的函数执行此操作,我的基本理论是这样的(希望你明白我的意思):

template<typename Func>
void process(Func func, ...) {
    func(...);
}

void myNewFunction(int, int, char*) {}

process(myNewFunction, 1, 2, "Hello World!");

如果进程可以返回与给定函数相同的类型,那就更好了(如果那不是要求太多:P)

我不希望任何库来执行此操作,我确信有一种方法可以使用 JUST C++。请帮忙:_|

【问题讨论】:

    标签: c++ function templates arguments


    【解决方案1】:

    在 C++11 中,您可以使用可变参数模板和完美转发:

    template<typename Func, typename... Args>
    void process(Func func, Args&&...) {
        func(std::forward<Args>(args)...);
    }
    

    例如:

    #include <iostream>
    #include <string>
    
    template<typename Func, typename... Args>
    void process(Func func, Args&&... args) {
        func(std::forward<Args>(args)...);
    }
    
    void myVoidFunction(std::string a, int b, double c) {
        std::cout << a << " " << b << " " << c << std::endl;
    }
    
    int main()
    {
        process(myVoidFunction, "Hello", 42, 3.14);
    }
    

    查看live example

    【讨论】:

    • 你的答案和@ecatmur 的答案本质上是相同的,只是你有Args&amp;&amp;... args,而他在process 签名中有Args... &amp;&amp;args。都可以接受吗?
    • 我很久以前试过这个,试过玩它,这个直接编译不了:
    • @Chowlett:不,他可能打错了。只有 Args&amp;&amp;... 在语法上是正确的。
    • 错误:在 '&&' 标记之前预期的 ',' 或 '...' 我在代码块中使用 gnu gcc
    • @Luka:哪个版本?另外,您是否使用-std=c++11 选项进行编译?如您所见,在现场示例中,我链接的代码编译并运行良好。
    【解决方案2】:

    使用可变参数模板:

    template<typename Func, typename Args...>
    void process(Func func, Args... &&args) {
        func(std::forward<Args>(args)...);
    }
    

    【讨论】:

      【解决方案3】:

      C++11 提供了两种方法来做这样的事情。一种是可变参数模板,另一种是std::bind。如果没有 C++11,您正在寻找 boost::bind 但您说没有库。这让你要么滚动你自己的bind 版本,要么做这样的事情:

      template<typename Func> void process(Func func) { func(); }
      template<typename Func, typename Arg1Type> void process(Func func, Arg1Type arg1) { func(arg1); }
      template<typename Func, typename Arg1Type, typename Arg2Type> void process(Func func, Arg1Type arg1, Arg2Type arg2) { func(arg1, arg2); }
      //etc.
      

      boost::functionboost::bind 看起来很像。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-03-28
        • 1970-01-01
        • 2015-04-15
        • 2017-12-18
        • 2022-06-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多