C++11模板和回调返回类型带有void专用化/重载



这是一个有点做作的例子,但它是再现我的问题所需的最少代码。

在这里,我传递一个函数回调,结果被转换为字符串并被推送到向量中。这适用于任何具有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,但没能成功。

我还缺少另一种方法吗?

if constexpr允许您有条件地编译代码,前提是条件取决于模板参数。这需要if constexpr的C++17和std::is_same_v型性状的#include<type_traits>

template<typename R>
void Example(std::vector<std::string> &vec, R (*func)()) {
if constexpr(std::is_same_v<R, void>) {
func();
} else {
auto r = func();
vec.push_back(std::to_string(r));
}
}

最新更新