if constexpr为什么不使这个核心常量表达式错误消失? [英] Why doesn't an if constexpr make this core constant expression error disappear?
问题描述
参考此问题.用于初始化constexpr
变量y
的核心常量表达式格式错误.给定了这么多.
In reference to this question. The core constant expression that is used to initialize the constexpr
variable y
is ill-formed. So much is a given.
但是,如果我尝试将if
转换为if constexpr
:
But if I try to turn the if
into an 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仍能提供的情况下:
The error persists. With GCC 7.2 still giving:
error: right operand of shift expression '(1 << -1)' is negative [-fpermissive]
但是我认为应该在丢弃的分支上不进行语义检查.
But I thought that the semantic check should be left unpreformed on a discarded branch.
通过constexpr
lambda进行间接寻址确实有帮助,但是:
Making an indirection via a constexpr
lambda does help, however:
template <typename T>
void foo(){
constexpr int x = -1;
constexpr auto p = []() constexpr { return x; };
if constexpr (x >= 0){
constexpr int y = 1<<p();
}
}
y
上的constexpr
说明符似乎改变了检查废弃分支的方式.这是预期的行为吗?
The constexpr
specifier on y
seems to alter how the discarded branch is checked. Is this the intended behavior?
@ max66 足以检查其他实现.他报告说,GCC(7.2.0/Head 8.0.0)和Clang(5.0.0/Head 6.0.0)均可重现该错误.
@max66 was kind enough to check other implementations. He reports that the error is reproducible with both GCC (7.2.0 / Head 8.0.0) and Clang (5.0.0 / Head 6.0.0).
推荐答案
该标准对if constexpr
的废弃声明并没有多说. [stmt.if]中基本上有两个关于这些的语句:
The standard doesn't say much about the discarded statement of an if constexpr
. There are essentially two statements in [stmt.if] about these:
- 在封闭模板中,未实例化丢弃的语句.
- 从废弃语句引用的名称不需要定义ODR.
这两种都不适合您使用:如果初始化,编译器会抱怨constexpr
是正确的.请注意,当您想利用实例失败时,需要使条件依赖于模板参数:如果该值不依赖于模板参数,则当模板是定义的.例如,此代码仍然失败:
Neither of these applies to your use: the compilers are correct to complain about the constexpr
if initialisation. Note that you'll need to make the condition dependent on a template parameter when you want to take advantage of the instantiation to fail: if the value isn't dependent on a template parameter the failure happens when the template is defined. For example, this code still fails:
template <typename T>
void f() {
constexpr int x = -1;
if constexpr (x >= 0){
constexpr int y = 1<<x;
}
}
但是,如果使x
依赖于类型T
,即使使用int
实例化f
也是可以的:
However, if you make x
dependent on the type T
it is OK, even when f
is instantiated with int
:
template <typename T>
void f() {
constexpr T x = -1;
if constexpr (x >= 0){
constexpr int y = 1<<x;
}
}
int main() {
f<int>();
}
这篇关于if constexpr为什么不使这个核心常量表达式错误消失?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!