Как динамически добавить параметр шаблона - PullRequest
0 голосов
/ 06 февраля 2020

Я новичок в C ++ и застрял с реализацией. Итак, моя проблема, как показано ниже:

У меня есть классы интерфейса, где единственная разница в классах - нет. параметров одной из его функций.

Например:

class foo3()
{
    private:
       function3(a,b,c) {}
};

class foo5()
{
    private:
       function5(a,b,c,d,e) {}
};

Чтобы обобщить их и использовать их, не зная их внутренней функциональности, я создал шаблон класса fooN и использовал специализацию шаблона, таким образом, основанный в параметре шаблона (int N) я могу выбрать правильный объект класса и выполнить некоторую обработку.

Теперь у меня есть алгоритм, в котором я создаю объект fooN template

class algo {
     public:
         fooN<5> fooObj;
     private:
 }

Можно ли динамически назначать этот параметр шаблона (5) во время выполнения или есть обходной путь?

В настоящее время я использую CMake для статической установки параметра шаблона.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2020

Возможно ли динамически назначить этот параметр шаблона (5) во время выполнения

Абсолютно нет. Все экземпляры шаблона происходят во время компиляции.

или есть обходной путь?

Может быть.

Вы, безусловно, можете создать экземпляр fooN для куча разных значений, и выбирать между ними во время выполнения. Самый простой способ - это что-то вроде

int algo(int n)
{
  switch(n) {
  case 3: return algoImpl<3>();
  case 5: return algoImpl<5>();
  default: return -1;
  }
}

, хотя вам, очевидно, нужно где-то получить параметры. Вы можете разумно сделать так, чтобы каждый algoImpl<N> принимал (во время выполнения) вектор значений аргументов, преобразовывал его в кортеж и использовал std::apply для вызова вашей базовой функции.

В настоящее время я использую CMake

Commiserations.

... для статической установки параметра шаблона.

Eww. Хранение битов вашей системы типов в файле конфигурации сборки кажется немного проблематичным. Что ваша система сборки знает о правильном значении N, чего нет в вашем коде?

0 голосов
/ 06 февраля 2020

К сожалению, это невозможно. Параметры шаблона должны быть известны во время компиляции

Когда компилятор встречает этот вызов функции шаблона, он использует шаблон для автоматической генерации функции, заменяющей каждое появление myType типом, переданным как фактический параметр шаблона (в данном случае int), а затем вызывает его. Этот процесс автоматически выполняется компилятором и невидим для программиста.

source

То есть все значения, с которыми может использоваться шаблон, должны быть известно во время компиляции.

Что вы можете сделать, это следующее

MyClassInterface* Factor(int p1, int p2, int p3) {
  if (p1 == 0 && p2 == 0 && p3 == 0)
    return new MyClass<0,0,0>();
  if (p1 == 0 && p2 == 0 && p3 == 1)
    return new MyClass<0,0,1>();
  etc;
}

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

Возможно, вы найдете решение, похожее на то, что вы пытаетесь сделать с списками инициализаторов, Это позволило бы вам сделать что-то вроде

my_type Var = {1, 2, 3, 4, 5, 6, ..., N};

Вы можете использовать такой список в качестве параметра функции.

Надеюсь, что это помогло вам с тем, чего вы пытаетесь достичь!

...