Create objects from template, type is entered by u

2019-04-14 23:15发布

问题:

I have a class which is a template. I want the program to ask the user what type he wants and then instantiate an object based on the type he chose. What would be the best way to do this? Something like this, but it doesn't work:

template <typename T> class Object {...};
cin >> type;
Object<type> newobject;

回答1:

Polymorphism

it will make objects template based and dynamic based on user input:

class Base
{
public:
  virtual ~Base() {};
};

template <typename T>
class Type : public Base
{
    T type;
};

int main()
{
    int i;
    cin >> i;

    Base *b;

    switch (i)
    {
    case 0: b = new Type<float>(); break;
    case 1: b = new Type<int>(); break;
    case 2: b = new Type<char>(); break;
    }

    // ...

    delete b;
}


回答2:

Templates in C++ must be resolved at compile time, so what you want here is impossible to do with templates. Your best bet will probably be implementing the Factory method pattern.



回答3:

There are at least two approaches.

First, create an instance using an if/switch statement based on user input, then store this instance in a pointer that does not know what the particular type is. It can be a pointer to an abstract base class, or a type erased pointer to a generated wrapper (like what std::function does), or a pointer to the equivalent of void and a variable to say what type it is to be used later. Variations of this are doable in C Java and many other languages.

A second way is to switch on user input, generate the object, then proceed to run code that knows the object type generated by template. You could do this with copy paste or macros or code generation in C and other C derived languages, but this kind of in language code generation is a newish technique in that lineage. Most similar generic code in other C derived languages is actually obscured type erasure.



回答4:

Template Functions

You can call a template function conditionally. This will generate all necessary code at compile time to support all needed types, but will only use those if your if statement calls that code. Then when you need to reference the user-inputted type in your function you can use 'T'.

template <typename T> class Object {...};

template <typename T> void myFunc() {
    Object<T> newobject;
    //statements
}

int main() {
    cin >> type;
    if (type == "int") myFunc<int>();
    if (type == "double") myFunc<double>();
    return 0;
}