В отношении этот вопрос. Ядро константного выражения, которое используется для инициализации переменной 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();
}
}
Спецификатор constexpr
на y
, по-видимому, изменяет способ проверки сброшенной ветки. Это предполагаемое поведение?
@max66 был достаточно любезен, чтобы проверять другие реализации. Он сообщает, что ошибка воспроизводится как с GCC (7.2.0/Head 8.0.0), так и с Clang (5.0.0/Head 6.0.0).