Вопрос

Можно ли вывести параметр шаблона без типа из параметра функции шаблона?

Рассмотрим этот простой шаблон:

template <int N> constexpr int factorial()
{
        return N * factorial<N - 1>();
}

template <> constexpr int factorial<0>()
{
        return 1;
}

template <> constexpr int factorial<1>()
{
        return 1;
}

Я хотел бы иметь возможность изменить factorial чтобы я мог альтернативно назвать это так:

factorial(5);

и пусть компилятор выясните значение n во время компиляции. Это возможно? Может быть, с каким -то причудливым дополнением C ++ 11?

Это было полезно?

Решение

Не может быть сделано, если у вас нет машины времени.

Параметр к функции обрабатывается во время выполнения. Да, в ваш Случай это буквальная постоянная, но это особый случай.

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

зачем вам это? Это просто так, что вам не нужно печатать <>S?

Другие советы

Ваш текущий код обычно пишутся следующим образом, я считаю:

constexpr factorial (int n)
{
    return n > 0 ? n * factorial( n - 1 ) : 1;
}

Если вы называете это с постоянной экспрессией, например factorial(5), Тогда все магии компилятора вступит в игру. Но если вы сделаете int a = 3; factorial(a), Тогда я думаю, что это вернется на обычную функцию - то есть у него не будет создан таблица поиска предварительно вычисленных ответов.

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

Я не думаю, что вы можете это сделать; Единственный способ, которым вы могли бы сделать это, - это иметь constexpr параметр функции, который будет передаваться тогда как template параметр для версии шаблона factorial, но constexpr Параметры функции не допущены.

Нет, это невозможно, если вы не хотите создать огромный оператор Switch:

int getFactorial( const int v )
{
  switch ( v )
  {
    case 1 : return factorial<1>();
    case 2 : return factorial<2>();
    //etc
    default:
       ;
  }
  return 0;
}

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

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

Используйте злой макрос:

#define factorial(X) factorial<X>()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top