& quot; если constexpr & quot; взаимодействие с & quot; попробовать в функции constexpr & quot; предупреждение

Я утверждаю что эта программа должен быть правильно сформирован: он объявляет функцию-член constexpr S<int>, Однако и GCC, и Clang отклоняют эту программу.

template<class T>
struct S {
constexpr int foo() {
if constexpr (std::is_same_v<T, int>) {
return 0;
} else {
try {} catch (...) {}
return 1;
}
}
};

int main()
{
S<int> s;
return s.foo();  // expect "return 0"}

GCC говорит:

ошибка: попробуйте в функции constexpr

Clang говорит:

ошибка: оператор не разрешен в функции constexpr

Ни один из них, кажется, не замечает, что оператор «try» находится в отброшенной ветви if constexpr заявление.

Если я фактор try/catch в без constexpr функция-член void trycatch()затем и Clang, и GCC снова довольны кодом, хотя его поведение должно быть эквивалентно несчастной версии.

template<class T>
struct S {
void trycatch() {
try {} catch (...) {}
}
constexpr int foo() {
if constexpr (std::is_same_v<T, int>) {
return 0;
} else {
trycatch();  // This is fine.
return 1;
}
}
};

Это

  • ошибка как в GCC, так и в Clang?
  • дефект в стандарте, который GCC и Clang добросовестно внедряют?
  • проблема качества реализации из-за «условная связь» из foo()?

(Неактуальный фон: я внедряю constexpr any::emplace<T>() для версии с поддержкой распределителя any чей распределитель может быть constexpr-per-P0639 (то есть может не хватать deallocate функция-член) или не может. В первом случае мы не хотим или не нуждаемся в try; в последнем случае нам нужно try для того, чтобы позвонить deallocate если конструктор T броски.)

7

Решение

Компиляторы подчиняются Стандарту. В проекте C ++ 17 N4659 говорится ([dcl.constexpr] / (3.4.4)):

Определение функции constexpr должно удовлетворять следующим требованиям:

  • его функция тела должен быть = delete, = defaultили компаунд-заявление что не содержит

    • попробуйте-блок, или же

И ни одно из правил для «исключенных заявлений», таких как else утверждение в вашем S<int>::foo переопределить это правило. Единственные особые вещи, которые указаны в отношении отброшенных операторов, — это то, что отброшенные операторы не создаются, а использование odr в опущенных операторах не требует определения используемого объявления и отбрасывается return операторы игнорируются при определении истинного типа возврата функции с типом возврата заполнителя.

Я не видел ни одной существующей проблемы C ++, обсуждающей это, и документ P0292R1, в котором предлагалось if constexpr не касается взаимодействия с функциями constexpr.

11

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]