Это немного надуманный пример, но наименьшее количество кода для воспроизведения моего вопроса.
Здесь я передаю обратный вызов функции, а результат преобразуется в строку и помещается в вектор. Это прекрасно работает для любого типа с to_string
реализацией. (Я использую указатели на функции вместо std :: function, потому что некоторые функции поступают из сторонних C библиотек)
#include <vector>
#include <string>
template<typename R>
void Example(std::vector<std::string> &vec, R (*func)()) {
auto r = func();
vec.push_back(std::to_string(r));
}
int main(int argc, char **argv ) {
std::vector<std::string> vec;
Example(vec, static_cast<int(*)()>([]() -> int{
return 0;
}));
Example(vec, static_cast<double(*)()>([]() -> double{
return 0.0;
}));
}
Однако один особый случай - void
. В этом случае я не хочу, чтобы что-либо было добавлено к вектору.
// This obviously does not compile.
Example(vec, static_cast<void(*)()>([](){
auto a = 0;
}));
Я знаю, что могу перегрузить Example
, то есть
void Example(std::vector<std::string> &vec, void (*func)()) {
func();
}
Но в моем приложении реального мира Example
НАМНОГО сложнее, и перегрузка приводит к большому количеству кода, вставленного в копию. Я попытался использовать type_traits
Но не смог заставить это работать.
Есть ли другой подход, который мне не хватает?