G++ 和 STD 11 在 constexpr 方面存在问题

Pau*_*nho 2 c++ compiler-errors constexpr c++11

我尝试在 g++ 和 clang++ 中使用相同的 constexpr,最新版本和参数“-std=c++11”。Clang 编译没有问题,但 G++ 返回错误。来源是:

#include <functional>

enum class LoggerLevel : unsigned {
    NO_LEVEL = 0,
    VERBOSE = 1 << 0,
    DEBUG = 1 << 1,
    INFO = 1 << 2,
    WARNING = 1 << 3,
    ERROR = 1 << 4,
    FATAL = 1 << 5,
    ALL_LEVELS = 0 | VERBOSE | DEBUG | INFO | WARNING | ERROR | FATAL,
};

constexpr LoggerLevel operator|(LoggerLevel lhs, LoggerLevel rhs) noexcept {
    return static_cast<LoggerLevel>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
}

constexpr LoggerLevel& operator|=(LoggerLevel& lhs, LoggerLevel rhs) noexcept {
    return lhs = lhs | rhs;
}

int main()
{
    auto x = LoggerLevel::ALL_LEVELS;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误是:

<source>: In function 'constexpr LoggerLevel& operator|=(LoggerLevel&, LoggerLevel)':

<source>:19:16: error: expression '(lhs = operator|(lhs, rhs))' is not a constant expression

     return lhs = lhs | rhs;

            ~~~~^~~~~~~~~~~

Compiler returned: 1
Run Code Online (Sandbox Code Playgroud)

还有 Godbolt 的例子:

https://godbolt.org/z/M6ERms

感谢您的帮助。

Ron*_*Ron 5

至少按照 C++14 之前的 C++14 标准进行编译,核心常量表达式求值不会值赋值或复合赋值运算符,这就是您所拥有的:

return lhs = lhs | rhs;
Run Code Online (Sandbox Code Playgroud)

C++11草案中的相关章节是5.19.2常量表达式(强调我的):

条件表达式是核心常量表达式,除非它涉及以下其中一项作为潜在计算的子表达式...

  • 作业复合作业