"constexpr if" vs "if" 与优化 - 为什么需要"constexpr"?
"constexpr if" vs "if" with optimizations - why is "constexpr" needed?
c 1z将根据条件将" constexpr"引入" constexpr" - 如果将一个分支之一根据条件删除。似乎很合理且有用。
但是,没有constexpr关键字不可能做到吗?我认为在编译期间,编译器应该知道在编译时间是否已知。如果是,即使是最基本的优化级别也应删除不必要的分支。
例如(请参阅Godbolt:https://godbolt.org/g/ipy5y5):
int test() {
const bool condition = true;
if (condition) {
return 0;
} else {
// optimized out even without "constexpr if"
return 1;
}
}
Godbolt Explorer表明,即使使用-O0的GCC -4.4.7也没有编译"返回1",因此它实现了Constexpr的承诺。显然,当条件是constexpr函数的结果时,这种旧的编译器将无法做到这一点,但事实仍然是:现代编译器知道条件是否是constexpr,并且不需要我明确地告诉它。
所以问题是:
为什么在" constexpr"中需要" constexpr"?
这很容易通过示例解释。考虑
struct Cat { void meow() { } };
struct Dog { void bark() { } };
和
template <typename T>
void pet(T x)
{
if(std::is_same<T, Cat>{}){ x.meow(); }
else if(std::is_same<T, Dog>{}){ x.bark(); }
}
调用
pet(Cat{});
pet(Dog{});
将触发汇编错误( wandbox示例),因为if
语句的两个分支都必须很好地形成。
prog.cc:10:40: error: no member named 'bark' in 'Cat'
else if(std::is_same<T, Dog>{}){ x.bark(); }
~ ^
prog.cc:15:5: note: in instantiation of function template specialization 'pet<Cat>' requested here
pet(Cat{});
^
prog.cc:9:35: error: no member named 'meow' in 'Dog'
if(std::is_same<T, Cat>{}){ x.meow(); }
~ ^
prog.cc:16:5: note: in instantiation of function template specialization 'pet<Dog>' requested here
pet(Dog{});
^
更改pet
使用if constexpr
template <typename T>
void pet(T x)
{
if constexpr(std::is_same<T, Cat>{}){ x.meow(); }
else if constexpr(std::is_same<T, Dog>{}){ x.bark(); }
}
仅要求分支可解析 - 只有与条件匹配的分支需要良好形成( Wandbox示例)。。
摘要
pet(Cat{});
pet(Dog{});
将根据预期进行编译和工作。
相关文章:
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 三元运算符和 if constexpr
- C++20. is_constant_evaluated() vs if constexpr
- LLVM覆盖被if-constexpr混淆了
- 在if constexpr中使用带参数包的概念时,升级到gcc 9后出现编译错误
- 是否可以使用"if constexpr"来声明具有不同类型和init-expr的变量
- 对'if constexpr'的错误理解
- 从语言设计层面来看,当编译时无法推断条件时,为什么"if constexpr"不衰减到"trival if"
- 如何让编译器忽略这个计算结果为 false 的 if-constexpr?
- 无法编译包含"if constexpr"的函数模板实例化
- 从“if constexpr”分支扩展对象生存期/范围
- MSVC 和 clang for if constexpr 分支的不同行为
- 禁用具有"if constexpr"和 SFINAE 的分支
- 'if constexpr branch'不会在模板函数内的 lambda 中被丢弃
- 斐波那契和'if constexpr'
- 从编译器优化和代码性能的角度来看,"if constexpr"与"if"
- if constexpr的False分支未在模板化lambda中丢弃
- 在“if constexpr”块中声明的变量的范围
- 编译器之间在丢弃的 if constexpr(false) 语句中实例化模板的行为不一致