问题
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 */ );
回答1:
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
回答2:
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.
回答3:
No, you can't. Types in C++ aren't objects, and they can't be used as values.
Depending what you actually need, you might be able to do something with type_info (or rather, pointers to them). This is not the type, and it can't be used to access the type, but it can be used for example in equality comparisons to determine whether two type_info objects refer to the same or different types.
回答4:
Depends on what you mean by "vector"
A specialization of std::tuple is a (compile-time) ordered collection of types.
You can index them (untested code):
typedef std::tuple<int, long, void, std::string, std::complex<float> Tuple;
typename std::tuple_element<1, Tuple>::type foo; // foo is of type long
You can do all sorts of manipulations (at compile-time) on tuples, and the results of these manipulations are types (or other tuples). C++14 formalizes (but did not invent) the idea of "index sequences", which let you do pretty much arbitrary tuple-type -> tuple-type transforms.
来源:https://stackoverflow.com/questions/19539345/vector-of-typedefs