【问题标题】:C++ Function with variable number and types of arguments as argument of another function具有可变数量和类型的参数的 C++ 函数作为另一个函数的参数
【发布时间】:2021-04-29 08:30:33
【问题描述】:

我想创建一个调用另一个函数并打印其参数的函数。
它应该与具有多种参数变量组合的许多函数(返回相同的结果)兼容。

我想要这样的东西:

int fun1(){}
int fun2(int i){}
int fun3(std::string s, int i){}

void execute_and_print(std::function f, ...)
{
///code
}

int main()
{
execute_and_print(&fun1);
execute_and_print(&fun2, 3);
execute_and_print(&fun3,"ff",4);
}

它可以打印:

executed function with arguments:
executed function with arguments: 3
executed function with arguments: ff, 4

在 C++ 中甚至可能吗?

【问题讨论】:

标签: c++ function bind


【解决方案1】:

在 C++17 中非常简单

template <typename F, typename... Args>
void execute_and_print(F f, Args... args)
{
    (std::cout << ... << args);
    f(args...);
}

在此之前还有额外的仪式

template <typename F, typename... Args>
void execute_and_print(F f, Args... args)
{
    int dummy[] = { (static_cast<void>(std::cout << args), 0)... };
    f(args...);
}

【讨论】:

  • 第一个和第二个示例在 MSVC C++17 和 C++14 中不起作用。
  • 第一个例子:错误:在'(std::cout
  • @pktiuk:现在应该修正错别字了。
【解决方案2】:

这不是万无一失的,但任何可能的错误都会在编译时被捕获(即代码不会编译)。它应该是工作文件,只要提供的参数与被调用函数的参数匹配,并且每个参数都存在匹配的&lt;&lt; 运算符。

template<class Fn, class...Args>
void execute_and_print(Fn fn, Args...args) {
    int f[sizeof...(Args)] = { (std::cout << args << ", ", 0)... };
    fn(args...);
}

请参阅https://en.cppreference.com/w/cpp/language/parameter_packsizeof... 命令实际上是元素的数量,而不是它们的组合大小。

【讨论】:

  • 我怀疑这东西在 C++ 中是否真的有效...i 甚至不是 constexpr。
  • 是的,很抱歉误导并感谢您指出这一点。将在答案中进行编辑。
  • 如果没有任何参数可能会出现问题,数组大小将为0(IDE和编译器会抱怨)。
【解决方案3】:

您可以使用模板来完成它,

template <class... Args>
void RunThrough(Args&& ... args)
{
    ([&](auto& input)
        {
            std::cout << input << ", ";
        } (args), ...);
}

template<class Func, class... Args>
decltype(auto) execute_and_print(Func f, Args&&... args)
{
    f(args...);

    std::cout << "executed function with arguments: ";
    RunThrough(args...);
    std::cout << std::endl;
}

您可以在 this 中使用 lambdas、std::function 对象和函数指针。

参考:https://stackoverflow.com/a/60136761/11228029

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 2016-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 1970-01-01
    • 2018-06-27
    相关资源
    最近更新 更多