How to put different template types into one vector

10,562

Solution 1

Option 1 : make sure that all different types of arguments derive from a base class and use pointers to that class. Note that this option is risky in terms of memory management. You might want to make it safer by using boost::shared_ptr instead of pointers. Otherwise, you must manually clean up when an item is being removed from the vector.

Option 2 (my personal favorite) : use Boost.Variant to make a typedef of all possible argument types and use that typedef as the argument type in std::vector

typedef boost::variant<ArgumentType1, ArgumentType2, ArgumentType3> ArgumentType;
std::vector<ArgumentType> vec;

Solution 2

The easiest way to do this would be to have a base Argument class, which is not templated, and then have the specific data types derive from it. (You could even make the templated version derive from the base class directly and just use those two classes.) Then you store them as pointers in a vector.

This does require having some sort of functions to access the argument values and perform any conversions as required.

Solution 3

You could use boost::variant (http://www.boost.org/doc/libs/1_38_0/doc/html/variant.html)
or boost::any ( http://www.boost.org/doc/libs/1_38_0/doc/html/any.html ) types

or void* - ugly and not typesafe
or implement own generic type which will have one interface and different templated implementation and will store pointer on this interface.

But I'm not sure that using similar types is good design.

Share:
10,562

Related videos on Youtube

APengue
Author by

APengue

Updated on April 17, 2022

Comments

  • APengue
    APengue about 2 years

    I'd like to construct a message with unknown length or number of arguments. I took a simple template like

    template <typename T> class Argument {
    public:
        int size;
        int type;
        T data;
    };
    

    and with some overloaded

    addMessage (int value) {
        Argument<int> *a = new Argument<int>;
        vec.push_back(a);
    }
    

    (same for string and so on) I try to push it all into one vector. I tried

    std::vector<Argument* > vec;
    std::vector<Argument<typename T>* > vec;
    std::vector<Argument<>* > vec;
    

    but nothing of this seems to work. Is there a way to do this? Thanks in advance.

  • APengue
    APengue about 15 years
    Looks like I was wrong when I thought templates are made to have "all the types" at hand. As there's is no Boost used in this project yet I'll stick with inheritance. thx
  • barsan-md
    barsan-md over 7 years
    std::variant is available since C++17. en.cppreference.com/w/cpp/utility/variant