Вызывающая функция с необязательным аргументом различного типа - PullRequest
2 голосов
/ 24 октября 2019

Я пытаюсь написать функцию вызывающей стороны, которая может принимать необязательный аргумент с переменным типом шаблона.

#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* допустимым типом?

1 Ответ

3 голосов
/ 24 октября 2019

Вы можете сделать большую часть этого с шаблоном переменной и совершенной пересылкой :

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, даже если объявлена ​​вызываемая функция 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
...