Подтвердить что ты не робот

С++ 11 - static_assert в функции constexpr?

Как правильно выполнить static_assert в функции constexpr? Например:

constexpr int do_something(int x)
{
  static_assert(x > 0, "x must be > 0");
  return x + 5;
}

Это недопустимый код С++ 11, потому что функция constexpr должна содержать только оператор return. Я не думаю, что стандарт имеет исключение из этого, хотя GCC 4.7 не позволяет мне скомпилировать этот код.

4b9b3361

Ответ 1

Это недопустимый код С++ 11, потому что функция constexpr должна содержать только оператор return.

Это неверно. static_assert в функции constexpr прекрасны. Что не очень хорошо, так это использование функциональных параметров в постоянных выражениях, как вы это делаете.

Вы можете выбросить, если x <= 0. Вызов функции в контексте, который требует постоянного выражения, не сможет скомпилировать

constexpr int do_something(int x) {
  return x > 0 ? (x + 5) : (throw std::logic_error("x must be > 0"));
}

Ответ 2

Это работает и является допустимым кодом С++ 11, потому что аргументы шаблона только время компиляции:

template <int x>
constexpr int do_something() {
    static_assert(x > 0, "x must be > 0");
    return x + 5;
}

Я столкнулся с теми же проблемами, что и с постоянными выражениями на С++. На данный момент существует несколько четких документов о constexprs. И обратите внимание, что в нем есть некоторые известные ошибки в gcc-проблеме, но ваша проблема, похоже, не является ошибкой.

Обратите внимание: если вы объявляете функции constexpr внутри классов, вы не можете использовать их внутри класса. Это также не является ошибкой.

Изменить: это разрешено в соответствии со стандартом: 7.1.3 состояния

... или составной оператор, содержащий только

  • null,
  • static_assert -declarations
  • объявления typedef и объявления-псевдонимы, которые не используются  определить классы или перечисления,
  • с использованием деклараций,
  • с использованием Директив,
  • и ровно один оператор return