Динамическое создание шаблона
У меня есть шаблон класса, и мне нужно объявить объект этого класса, не определяя параметры типа, так что я могу определить их условно позже, например:
template<typename T>
class A{
public:
A(T v){var = v};
~A(){};
T var;
}
int main(){
A<>* object; // Or sometihng along these lines...?
if(/* something*/)
object = new A<float>(0.2f);
else{
object = new A<int>(3);
}
}
Ответы
Ответ 1
Ну, вы, конечно, не можете этого сделать. Вам нужно сделать вывод A из другого класса, например:
template<typename T>
class A : public B {
public:
A(T v){var = v};
~A(){};
T var;
}
int main(){
B* object;
if(/* something*/)
object = new A<float>(0.2f);
else{
object = new A<int>(3);
}
}
Ответ 2
Самый простой способ сделать это - использовать другую функцию.
template<typename T> void other_stuff(A<T>* object) {
// use T here
}
int main() {
if (condition)
other_stuff(new A<float>(0.2f));
else
other_stuff(new A<int>(3));
}
Это сохраняет всю информацию о типе и не зависит от наследования. Недостатком наследования является то, что T не может появляться в каких-либо функциональных интерфейсах, но в такой ситуации он может.
Ответ 3
Шаблоны раскрываются во время компиляции, поэтому ваша проблема на самом деле такая же, как показано ниже:
struct A_float { // struct is easier when everything public
A(float v) : var(v) {} // (use the ctor-initializer please!)
~A() {}
float var;
}; // don't forget the semicolon
struct A_int {
A(int v) : var(v) {}
~A() {}
int var;
};
int main() {
WhatType* object; // What type here?
if (/* something*/)
object = new A_float(0.2f);
else
object = new A_int(3);
}
Надеюсь, если вы увидели приведенный выше код, вы бы подумали (а также "возможно, мне следует использовать шаблоны") "Мне понадобится общий базовый класс для этого, иначе я буду рефакторинг".
Когда вы генерируете два типа во время компиляции, используя шаблон класса, этот вывод один и тот же.
- Я бы порекомендовал рефакторинг, выбрав решение, подобное Puppy; создание иерархии наследования просто для обхода недостатка логического потока программы - это программирование в обратном направлении!
Ответ 4
Вы можете использовать указатель void при создании объекта класса A
Посмотрите следующий образец кода:
template<typename T>
class A
{
public:
A(T v){var = v;};
A(){};
~A(){};
T var;
};
int main(){
A<void *> object;
if(1){ // do this
object = new A<float>(0.31f);
// type cast void pointer to get value
cout<<*(float*)object.var;
}
else{ // else do this
object = new A<int>(34);
// type cast void pointer to get value
cout<<*(int*)object.var;
}
}