C ++ 11 - static_assert внутри функции constexpr? - PullRequest
51 голосов
/ 24 декабря 2011

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

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

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

Ответы [ 2 ]

59 голосов
/ 24 декабря 2011

Это недопустимый код C ++ 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"));
}
23 голосов
/ 24 августа 2012

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

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

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

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

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

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

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