Question: Assume I have the following 2 classes `Super` and `Deriv` where `Deriv` is a subclass of `Super`.

`Super` and `Deriv` are both templated classes. I want to create a `vector` of type `Super<?>`. Where the `?` signifies any type. Currently I have come up with this:

```
#include <iostream>
#include <vector>

template <typename T>
class Super {
public:
    T val;
    Super(T val) : val(val) {};
};

template <typename T>
class Deriv : public Super<T> {
public:
    Deriv(T val) : Super<T>(val) {};
};

int main() {
    std::vector<Super*> a;
    a.push_back(new Deriv<int>(1));
    a.push_back(new Deriv<float>(1.0f));

    std::cout << a[0]->val << std::endl;
    return 0;
}

```

Of course this does not work because `std::vector<Super*>` needs a template type like `std::vector<Super<int>*>`. However the problem with this is I can only add items to the vector of type `Super<int>*` and not `Super<float>*`.

How can I alter this code to allow me to add a `Super` type or it's derivatives to a vector which has any template type like `int`, `float`, `short` etc?

Answer: 
This

```
std::vector<Super*> a;

```

Is wrong.

There is no type named `Super` in your code. Yes, you declared something named "Super", but it's not a class, it's a class template.

The name of the feature says it all. It's a template. The compiler will use `Super` to generate new types at compile time.

For example, `Super<int>` Refer to the class generated by the compiler when filling the hole `T` in the `Super` template.

So why `a[0]->val` cannot possibly work? Well, imagine this:

```
template<>
struct Super<std::string> {
    std::string my_val;
};

```

We specialize `Super` so when instantiated with `std::string`, it no longer have the `val` member, but the `my_val` member.

Now, what do you expect this code to do?

```
std::vector<Super*> a;
a.push_back(new Deriv<std::string>);

std::cout << a[0]->val << std::endl;

```

Quite puzzling isn't it? You'd need a compilation error at runtime. Since the existence (or non existence) of variable is determined at compile time, it's not possible.

---

Now how can we solve your problem?

In your case, it would be as simple as adding an interface above `Super`, and exposing functions that implements behaviors needed to do your calculations:

```
struct Interface {
    void print(std::ostream) const = 0;
    bool lessThan(double) const = 0;
};

template <typename T>
struct Super : Interface {
    T val;

    Super(T val_) : val{val_} {};

    // We implement the needed behavior.
    void print(std::ostream o) const override {
        o << val << std::endl;
    }

    // Example of calculation
    bool lessThan(double rhs) const override {
        return val < rhs;
    }
};

```

Now you can do:

```
std::vector<Interface*> a;

// ...

a[0]->print(std::cout);
a[0]->lessThan(3.7);

```
Create a new class `RealSuper` that cache the type is a possible workaround. 

It is not perfect, but I am afraid that it can't be much better than this :-

```
class RealSuper{                                //<-- new class
    public: enum TYPE{ type_int, type_float, type_notIni };  // (yes, it is awkward)
    TYPE typee = type_notIni;
};
template <typename T>   class Super : public RealSuper { //<-- modify
    public:  T val;
    Super(T val) : val(val) {
        if( std::is_same<T, int>::value ){
            typee = type_int;
        }else if( std::is_same<T, float>::value ){
            typee = type_float;
        }
    };
};
template <typename T>  class Deriv : public Super<T> {
    public: Deriv(T val) : Super<T>(val) {};
};
int main() {
    std::vector<RealSuper*> a;
    a.push_back(new Deriv<int>(1));
    a.push_back(new Deriv<float>(1.0f));
    for(auto ele: a){
        switch( ele->typee ){
            case RealSuper::TYPE::type_int: {
                int value=static_cast<Super<int>*>(ele)->val;
                std::cout << value << std::endl; 
            };break;
            case RealSuper::TYPE::type_float :{
                float value=static_cast<Super<float>*>(ele)->val;
                std::cout << value << std::endl; 
            };break;
        }
    }
    return 0;
}

```

[live demo](http://coliru.stacked-crooked.com/a/19bf7bd4c65f898c)
-----------------------------------------------------------------

Here is another [demo](http://ideone.com/mSdipc) to show an approach using the virtual function.