G ++ и STD 11 имеют проблемы с constexpr - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь использовать один и тот же constexpr в g ++ и clang ++, как в последней версии, так и с параметром "-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;
}

И ошибка:

<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

И пример Godbolt:

https://godbolt.org/z/M6ERms

Спасибо за любыепомощь.

1 Ответ

0 голосов
/ 08 октября 2018

Скомпилируйте, по крайней мере, для стандарта C ++ 14, как до C ++ 14, ядро ​​ константное выражение вычисление будет не оценивать назначение или составной оператор присваивания, которыйчто у вас есть:

return lhs = lhs | rhs;

Соответствующей главой в черновике C ++ 11 является 5.19.2 Постоянные выражения (выделено мной):

Условное выражение является основным константным выражением, если оно не включает одно из следующих значений в качестве потенциально вычисляемого подвыражения ...

  • присваивание или составное присваивание
...