Определенные пользователем литеральные аргументы не являются constexpr?

Я тестирую литералы, определяемые пользователем. Я хочу, чтобы _fac возвращала факториал числа.

Вызов функции constexpr работает, но это не позволяет мне сделать это с шаблонами, поскольку компилятор жалуется, что аргументы не являются и не могут быть constexpr.

Меня это смущает - разве литералы не являются константными выражениями? 5 в 5_fac всегда является литералом, который может быть оценен во время компиляции, так почему я не могу использовать его как таковой?

Первый метод:

constexpr int factorial_function(int x) {
  return (x > 0) ? x * factorial_function(x - 1) : 1;
}

constexpr int operator "" _fac(unsigned long long x) {
  return factorial_function(x); // this works
}

Второй метод:

template <int N> struct factorial_template {
  static const unsigned int value = N * factorial_template<N - 1>::value;
};
template <> struct factorial_template<0> {
  static const unsigned int value = 1;
};

constexpr int operator "" _fac(unsigned long long x) {
  return factorial_template<x>::value; // doesn't work - x is not a constexpr
}
23
задан jotik 1 February 2017 в 12:53
поделиться