这些 if 语句会在编译时解析吗?
Will those if statements be resolved at compile time?
嘿伙计们,我有几个问题无法自己回答。
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
使用变量是个好主意吗?还是有更好的?(我也尝试使用函数指针,它有效,但它对性能不友好)
编辑:
1.好吧,你们中的很多人告诉我,我可以超载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
模板的非专用版本,这基本上是对空函数的调用。调用空函数是个好主意吗?
在C++17中,您可以使用constexpr if
来确保;
如果您无法访问 C++17,仍然有一些 SFINAE 技巧(例如,您可以在一些虚拟的额外参数上重载您的函数)可以完成这项工作,但无论如何,您的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);
// ...
}
从您的代码中不清楚 -success
参数有点碍事 - 但也许甚至函数重载就足够了(正如其他人指出的那样)。
您正在执行的操作看起来像手动重新创建函数重载系统。让编译器承受压力:
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);
// ...
}
是的,因为T
和some_known_type_1
在编译时是已知的,所以现代编译器将优化if语句。原因是:几十年来,它们的设计目的是检测死代码分支并消除它们。如果您没有启用任何编译器优化,那么出于同样的原因,答案是否定的。
auto
在那个上下文中不太有意义,因为你正在处理泛型代码,请改用T bar = check;
。
您未使用的分支可能会被优化(至少 clang/gcc 可以这样做 - https://gcc.godbolt.org/在线检查),正如其他人在即将到来的 C++17 中指出的那样constexpr if
将是此类编译时任务的首选。
最后通知:由于没有完全了解您的代码,我真的不能说,但仅从该片段来看,您似乎正在重新发明类型重载或模板专用化。你应该退后一步,考虑更大的图景。
- 二叉排序树无法编译
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- 从语言设计层面来看,当编译时无法推断条件时,为什么"if constexpr"不衰减到"trival if"
- 在编译时计算"if"子句
- C++ if 语句范围内的宏未编译
- C++ 带有 if 语句的家庭作业编译错误
- 无法编译包含"if constexpr"的函数模板实例化
- 这些 if 语句会在编译时解析吗?
- 为什么"if constexpr"不使用Visual Studio 2017 15.3进行编译?
- 为容器中的不同字符串类型实现编译时"static-if"逻辑
- 如何在Visual Studio中使用#if指令编译时检查常量变量
- 如何在C++中的编译时应用if
- 如何通过编译时"if"返回 T 值?
- if(null) 正在使用 clang++ 编译的特定计算机中执行
- 如何编译器编译 if 语句
- C++计算器程序正在跳过if语句,即使它编译得很好
- 为什么我会得到一个编译错误,上面写着error:“else”而没有前面的“if”
- 编译时已知条件下的标准if/else
- SDL c++: if函数不工作.编译精细-逻辑错误