Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vector of typedefs

Is it possible in ANY way to have a vector of type(def)s in C++11/14 ?

The first thing I tried was have a vector of a base class and somehow get the typedef from it's derived form but I can't get this to work whatever I try (not possible most likely).

Pseudo-C++:

class base
{
   /* somehow access 'type' from derived */
}

template <typename T>
class derived : base
{
   typedef T type;
}

vector<base*> vec;
vec.push_back( new derived<int> );
vec.push_back( new derived<double> );
vec.push_back( new derived<float> );
vec.push_back( new derived<string> );

for(auto& item : vec)
   static_cast< item->type >( /* something */ );
like image 959
user1233963 Avatar asked Oct 21 '25 07:10

user1233963


2 Answers

Boost MPL provides a compile time construct for this, for example:

typedef boost::mpl::vector<int, double, std::string, CustomA, CustomB> seq_of_types;

You can interact with this at compile type using the extensive set of meta functions defined in mpl. There are also some run-time crossover functions too. The important point here is that this is a sequence of types, there are no instances of each type to interact with. Even the runtime functions only allow interacting with types.

Boost Fusion (and std::tuple) steps in here to provide a runtime heterogenous container, so for example

boost::fusion::vector<int, double, std::string> v{10, 100., "Foo"};

Now at compile time, you have access to the type information of each entry, and at runtime you have an instance of each type in the sequence to work with.

It could be possible that what you are trying to achieve could be done with plain inheritance without having to resort to the above, so the vector holds a pointer to base class, which has a virtual function which is overriden in the derived classes which does what you want. This is possibly the cleanest.

Alternatively, the same is possible, without resorting to using inheritance if you use a variadic type such as boost::variant, for example:

std::vector<boost::variant<int, double, std::string>> entries;

Now each entry is one of the types of int, double, std::string. Then as you iterate, you can use a static visitor to operate on the specific instance. I think I've answered a question on SO a while ago which demonstrates this.

So which will it be?

EDIT: base on your last comment, then the latter (variant) doesn't really fly, and nor does plain inheritance. I think a fusion vector is really not necessary either as you don't need an instance of each type. The most suitable thing for you then is the mpl::vector, and use the runtime function mpl::for_each

like image 159
Nim Avatar answered Oct 23 '25 21:10

Nim


Maybe you could look into Loki's type lists (see here). There's a question on to use them here. I think this is as close as it gets to what you're looking for. Boost MPL also has something like that (see this question), with type lists and type vectors.

like image 40
jbat100 Avatar answered Oct 23 '25 19:10

jbat100



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!