嘿伙计们,我几乎无法回答自己的问题。
void someFunc_1(some_known_type_1 bar);
void someFunc_2(some_known_type_2 bar);
void someFunc_3(some_known_type_3 bar);
template < class T, T success>
void foo(T check) {
// ...
auto bar = check;
if (std::is_same<T, some_known_type_1>::value) {
someFunc_1((some_known_type_1) bar);
// ...
}
else if (std::is_same<T, some_known_type_2>::value) {
someFunc_2((some_known_type_2) bar);
// ...
}
else if (std::is_same<T, some_known_type_3>::value) {
someFunc_3((some_known_type_3) bar);
// ...
}
// ...
}
上面的代码是我的模板函数的最简单版本,用于识别//处理错误。我以这种方式编写这个函数以避免代码重复 - 如果我必须使用模板特化,我会发现在每个版本中部分代码都会重复。
问题:
1.这些if语句是否会在编译时解决?我想他们会,但我不确定。代码正在编译我测试它。
2.正常如果我没有使用变量auto bar
我最终会遇到每个if语句的编译时错误(类型不匹配)。 因此使用auto
变量是一个好主意?或者有更好的吗?(我也尝试使用函数指针,它有效,但它不是性能友好的)
编辑:
好的,你们这么多人告诉我,我可以超载someFunc
,所以我就这样做了。但我现在有了新的问题:调用空虚函数是明智的吗?
新版本的代码
///////////////////////////////////
// someFunc:
// - this function in my original code handles different kinds of errors.
// - overloaded for 2 different types (some_known_type_1 & some_known_type_2).
// - with "Catch-all do-nothing" template.
inline void someFunc (some_known_type_1 bar) {
// Do something...
}
inline void someFunc (some_known_type_2 bar) {
// Do something...
}
// Catch-all do-nothing:
template <class T>
inline void someFunc(const T& bar) { /* I am empty... */ };
///////////////////////////////////
// Errchk: (Error check)
template < class T, T success> inline
void errchk(T check) {
if (check != success) {
std::cout << "there was an error !!!" << std::endl;
// Handle Error:
someFunc( check );
}
}
// Few additional macros to simplify call to errchk function:
#define ERRCHK_BOOL(_check) errchk <bool, true> (_check);
#define ERRCHK_TYPE_1(_check) errchk <some_known_type_1, type_1_success_value> (_check);
#define ERRCHK_TYPE_2(_check) errchk <some_known_type_2, type_2_success_value> (_check);
///////////////////////////////////
// program main function:
int main() {
bool error = false; // this value will be recognized as an error by errchk function;
ERRCHK_BOOL(error);
some_known_type_1 error_1 = type_1_error_value // same...
ERRCHK_TYPE_1(error_1);
some_known_type_2 error_2 = type_2_error_value // same...
ERRCHK_TYPE_2(error_2);
}
好的,如果仔细观察,你会看到我没有为bool类型重载someFunc
,因此每次使用ERRCHK_BOOL(***);
时,我都会调用someFunc
的非专业版本模板,这基本上是对空函数的调用。 调用空函数是个好主意吗?
答案 0 :(得分:4)
在 C ++ 17 中,您可以使用constexpr if
来确保;
如果您无法访问C ++ 17,那么仍然会有一些SFINAE技巧(例如,您可以在某些虚拟额外参数上重载您的函数)来完成这项任务,但可能是{{1}无论如何,语句将在编译时解析。
至于if
部分,问题有点不清楚。在这里使用auto bar
似乎完全正常,尽管它与auto
完全相同。
我不得不说,一个简单的模板专业化可能会让同样的工作更清晰:
T bar
从您的代码中不清楚 - void someFunc_1(some_known_type_1 bar);
void someFunc_2(some_known_type_2 bar);
void someFunc_3(some_known_type_3 bar);
template < class T, T success>
void foo(T check) {
// ...
}
template <some_known_type_1 success>
void foo<some_known_type_1, success>(some_known_type_1 check) {
someFunc_1(check);
// ...
}
参数有点妨碍 - 但即使是函数重载也足够了(正如其他人所说)。
答案 1 :(得分:2)
您正在做的事情就像手动重新创建功能过载系统一样。让编译器承受压力:
void someFunc(some_known_type_1 bar);
void someFunc(some_known_type_2 bar);
void someFunc(some_known_type_3 bar);
template < class T, T success>
void foo(T check) {
someFunc(check);
// ...
}
答案 2 :(得分:1)
是的,因为在编译时已知T
和some_known_type_1
,现代编译器将优化if语句。原因是:它们在过去几十年中被设计用于检测死代码分支并消除它们。如果你没有启用任何编译器优化,那么答案将是no,原因相同。
答案 3 :(得分:0)
auto
在上下文中没有意义,因为您正在处理通用代码,请改用T bar = check;
。
您未使用的分支机构可能会进行优化(至少是clang / gcc这样做 - 在线查看https://gcc.godbolt.org/),正如其他人在即将推出的C ++ 17中所指出的constexpr if
将是您的首选对于这样的编译时任务。
最后通知:由于没有完全了解您的代码,我无法真实地说,但仅从该片段看来,您似乎正在重新发明类型重载或模板专业化。你应该退一步考虑更大的图景。