Dynamic Template Instantiation

2020-02-25 08:22发布

I've got a class template, and I need to declare an object of that class, without defining the type parameters, so that I can define them conditionally later, e.g.:

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);
    }
}

标签: c++ templates
4条回答
放荡不羁爱自由
2楼-- · 2020-02-25 08:29

Templates are expanded at compile-time, so your problem is really just the same as the following:

struct A_float {            // struct is easier when everything's 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);
}

Hopefully if you saw the above code, you'd think (as well as "maybe I should be using templates") "I am going to need a common base class for this, or else I'll refactor".

When you generate the two types at compile-time using a class template, this conclusion is the same.

  • I'd recommend the refactoring, going for a solution like Puppy's; creating an inheritance hierarchy just to work around a program logic flow flaw is programming backwards!
查看更多
再贱就再见
3楼-- · 2020-02-25 08:36

You can use void pointer while create object of class A
Look at Following code sample :

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;    
    }
}
查看更多
爷的心禁止访问
4楼-- · 2020-02-25 08:46

Well, you certainly can't do that. You'll have to make A derive from another class, for example:

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);
    }
}
查看更多
▲ chillily
5楼-- · 2020-02-25 08:51

The easiest way to do this is to use another function.

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));
}

This maintains all type information and does not depend on inheritance. The disadvantage of inheritance is that T cannot appear in any function interfaces, but with this situation it can.

查看更多
登录 后发表回答