这是一个有点做作的例子,但它是再现我的问题所需的最少代码。
在这里,我传递一个函数回调,结果被转换为字符串并被推送到向量中。这适用于任何具有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));
}
}