问题描述
参考此问题.用于初始化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为什么不使这个核心常量表达式错误消失?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!