在参照这个问题。用于初始化的核心常量表达式constexpr
多变的y
格式不正确。这么多是给定的。
但如果我尝试转动if
进入一个if constexpr
:
template <typename T>
void foo() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1 << x;
}
}
int main(){
foo<int>();
}
错误仍然存在。 GCC 7.2 仍然给出:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
但我认为语义检查应该在废弃的分支上不执行。
通过a进行间接constexpr
然而 lambda 确实有帮助:
template <typename T>
void foo(){
constexpr int x = -1;
constexpr auto p = []() constexpr { return x; };
if constexpr (x >= 0){
constexpr int y = 1<<p();
}
}
The constexpr
说明符y
似乎改变了检查废弃分支的方式。这是预期的行为吗?
@max66很友善地检查了其他实现。他报告说,GCC (7.2.0 / Head 8.0.0) 和 Clang (5.0.0 / Head 6.0.0) 都可以重现该错误。
该标准并没有过多说明废弃的声明 of an if constexpr
。 [stmt.if] 中基本上有两个关于这些的陈述:
- 在封闭模板中,废弃的语句不会被实例化。
- 从废弃语句引用的名称不需要定义 ODR。
这些都不适用于您的使用:编译器抱怨的是正确的constexpr
如果初始化。请注意,当您想要利用模板参数时,您需要使条件依赖于模板参数实例化失败:如果该值不依赖于模板参数,则当模板参数为defined。例如,这段代码仍然失败:
template <typename T>
void f() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1<<x;
}
}
但是,如果你使x
取决于类型T
没关系,即使当f
实例化为int
:
template <typename T>
void f() {
constexpr T x = -1;
if constexpr (x >= 0){
constexpr int y = 1<<x;
}
}
int main() {
f<int>();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)