views:

367

answers:

3

Hi,

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.

+3  A: 

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.

bb
+7  A: 

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;
Benoît
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
DaClown
+4  A: 

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.

Daemin