具有不同类型的可选参数的调用函数

Caller function with optional argument of varying type

我正在尝试编写一个可以采用不同模板类型的可选参数的调用函数。

#include <iostream>
#include <string>

void f_int(int x){std::cout << "f_int\n";}
void f_double(double x){std::cout << "f_double\n";}
void f_void(void){std::cout << "f_void\n";}

template<typename T>
void caller(void (*fun)(T), T arg)
{
    (*fun)(arg); 
}


int main()
{
  caller(f_int, 3);
  caller(f_double, 2.1);
  caller(f_void);         // compilation error
  caller(f_void, void);   // compilation error
  void* p;
  caller(f_void, *p);     // compilation error
}

写这段代码时,我希望 T 可以是 void 类型。是真的吗?如果是,为什么上面的代码不起作用? void 是有效类型还是仅 void* 是有效类型?

您可以使用 variadic template and perfect forwarding:

来完成大部分工作
template<typename F, class... Args>
void caller(F func, Args&&... args) {
    func(std::forward<Args>(args)...);
}

//...

caller(f_int, 3);
caller(f_double, 2.1);
caller(f_void);

您也可以使用 auto return 函数模板中被调用函数的值,即使已声明被调用函数 void:

int f_int(int x) {
    return x*2;
}
double f_double(double x) {
    return x*1.5;
}
void f_void(void) {
    std::cout << "f_void\n";
}

template<typename F, class... Args>
auto caller(F func, Args&&... args) {          // note the "auto"
    return func(std::forward<Args>(args)...);  // and return
}

//...

auto rv1 = caller(f_int, 3);
auto rv2 = caller(f_double, 2.1);
caller(f_void);                                // you can't assign void though