gpt4 book ai didi

c++ - 为什么 if constexpr 不会使这个核心常量表达式错误消失?

转载 作者:IT老高 更新时间:2023-10-28 12:41:38 30 4
gpt4 key购买 nike

引用 this question .用于初始化 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]

但我认为语义检查应该留在丢弃的分支上。

通过 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();
}
}

y 上的 constexpr 说明符似乎改变了检查丢弃分支的方式。这是预期的行为吗?


@max66 非常友好地检查了其他实现。他报告说,GCC (7.2.0/Head 8.0.0) 和 Clang (5.0.0/Head 6.0.0) 都可以重现该错误。

最佳答案

标准对 if constexprdiscarded statement 没有多说。 [stmt.if] 中有两个关于这些的声明:

  1. 在封闭模板中,丢弃的语句不会被实例化。
  2. 从废弃语句中引用的名称不需要定义 ODR。

这些都不适用于您的使用:编译器在初始化时提示 constexpr 是正确的。请注意,当您想利用 实例化 失败时,您需要使条件依赖于模板参数:如果值不依赖于模板参数,则失败发生在模板已定义。例如,这段代码仍然失败:

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>();
}

关于c++ - 为什么 if constexpr 不会使这个核心常量表达式错误消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46512248/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com