c++ - clang 提示 constexpr 函数以防 switch 语句

标签 c++ c++11

struct X
    {
    enum class E
    {
        A,B
    };

    static constexpr X A()
    {
        return X{E::A};
    }

    static constexpr X B()
    {
        return X{E::B};
    }

    constexpr operator E() const
    {
        return a;
    }
    E a;
};

template <typename T>
struct Y
{
    void f()
    {
        // without this line clang errs
        // const auto & x = this->x;
        switch(x)
        {
            case X::A():
            case X::B():
            default: return;
        }
    }

    X x = X::A();
};

int main()
{
    Y<int>{}.f();
}

如果片段中没有标记行,clang 会出现以下错误:

error: case value is not a constant expression case

X::B():

但是我尝试了 gcc,它编译得很好。任何人都知道 gcc 是否宽松或 clang 有一些错误?

参见 godbolt (clang 8.0.0):https://godbolt.org/z/ETe5WQ 然而 (gcc 8.3) 编译良好(也在 godbolt 上)并尝试了其他版本的 gcc 并且也很好

更新:

打开一个bug

最佳答案

Clang (8.0.0) 在这里有一个错误。

如果你编写 constexpr auto A = X::A(); 并在你的 switch 语句中使用 case A:,你会得到同样的编译错误(说 A 不是 常量表达式)。

但是,如果您删除大小写,它可以正常编译(这意味着 A 一个有效的 constexpr => 与之前的错误)。

此外,switch(x) 失败,而 switch(this->x) 成功。自 x == this->x在您的情况下,这绝对是一个错误。

正如 chtz 所提到的,clang (5/6) 似乎工作得很好。这不是争论,而是明显的倒退。

更新:正如 OP 所提到的,他们提交了 bug report .

关于c++ - clang 提示 constexpr 函数以防 switch 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55359614/

相关文章:

c++ - 如何随机化程序的窗口标题?

c++ - 为什么 C++11 不支持这样的名称查找?

c++ - 是否可以在 vector 的构造函数中使用 lambda 函数?

c++ - 当 pragma for 内有 pragma for 时,OpenMP 中会发生什么?

c++ - 为什么 “delete *this” 会编译?

c++ - 为什么 std::shuffle 采用右值引用?

c++ - 期望在 GMock 中调用 Factory 返回 unique_ptr

c++ - 如何将临时 C 数组传递到 constexpr 容器中

c++ - 使用 chrono 存储毫秒的可移植方式

c++ - Apache Kafka 可以与 C++ 一起使用吗?