Любой способ обойти тот факт, что C ++ не поддерживает шаблоны времени выполнения? - PullRequest
0 голосов
/ 18 декабря 2011

У меня есть шаблонный класс, который получает два аргумента шаблона.

template <class T,class A>
class Z{...};

Скажем, у меня есть четыре типа T и одинаковое количество для A. Итак, есть варианты 16 !

Если я хочу выбрать один из них во время выполнения, мне нужно написать огромный и отвратительный случай.

Я знаю, что C ++ не поддерживает шаблоны времени выполнения.

Есть ли другой способ сделать это?

Ответы [ 5 ]

3 голосов
/ 18 декабря 2011

Способ достижения чего-то похожего состоит в добавлении зависимостей к class Z и предоставлении их во время выполнения - которое известно как шаблон стратегии .

Конечно, это означает, что class Z больше не шаблонируется со всем, что это влечет за собой. Но на самом деле нет никакого способа получить свой пирог и съесть его: шаблоны являются конструкцией во время компиляции, а вы спрашиваете о способах настройки чего-либо во время выполнения. Вы не можете настроить тип во время выполнения, только объект.

3 голосов
/ 18 декабря 2011

Нет, действительно нет. В природе шаблонов заложено, что это абсолютно и абсолютно невозможно.

0 голосов
/ 20 декабря 2011

Это может или не может соответствовать вашим потребностям, но простой общий интерфейс звучит так, как вы хотите:

class Z_interface{ //abstract interface
public:
    virtual ~Z_interface() {} //virtual destructor
    virtual void func()=0; //virtual member
};

template <class T,class A>
class Z : public Z_interface { //implimentation
public:
    virtual ~Z_interface() {}
    virtual void func() {}
};

int main() {
    std::unique_ptr<Z_interface> ptr;
    switch(stuff) { //make the correct type
    case 0: ptr = std::unique_ptr<Z_interface>(new Z<int, char>()); break;
    case 1: ptr = std::unique_ptr<Z_interface>(new Z<int, short>()); break;
    case 2: ptr = std::unique_ptr<Z_interface>(new Z<long, char>()); break;
    case 3: ptr = std::unique_ptr<Z_interface>(new Z<long, short>()); break;
    };
    ptr->func(); //don't care about the type anymore, just the algorithms
}
0 голосов
/ 19 декабря 2011

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

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

Z<int, std::string> z; // At this point a new class called Z<int, std::string> is defined, then the code to instantiate it at run time is generated.

Это может быть полезно для чтения: стандартная практика c ++: классы виртуального интерфейса и шаблоны

Может быть, это то, что вы ищете? Подобные вещи, использующие полиморфизм и виртуальные классы ..

class Z{
public:
    virtual void doSomething();
};

class ZT : public Z {
public:
    void doSomething();
};

class ZA : public Z {
public:
    void doSomething();
};

...

void useClasses(Z* ptr) {
    ZT* ztPtr = dynamic_cast<ZT*>(ptr); // Runtime conversion
    if (ztPtr) {
         // do specific stuff for this type
    } else {
         ptr->doSomething(); // generic behaviour that'll call whichever class ptr actually is
    }
}
0 голосов
/ 19 декабря 2011

Я не говорю, что это хорошее решение, но я видел его реализованным в прошлом: вы можете хранить код для вашего шаблонного класса в файле ресурсов и скомпилировать его во время выполнения в подключаемый модуль!

Кстати, я бы предложил реорганизовать проблему так, чтобы вместо создания экземпляров шаблонов MN вам был нужен только M + N; Я не знаю, возможно ли это в вашей проблеме, но обычно так, например, если вы переводите с одного типа на другой, обычно можно ввести промежуточное представление, которое работает для всех типов. Вам все еще нужен либо случай, либо форма полиморфизма для обработки различного типа, но это отчасти неизбежно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...