Reputation: 2150
I am trying to create a type-map in C++ using std::map and Type class which stores the type. Then there is one base class Base and some Derived classes which i want to store.
template <typename T>
class Type {
public:
Type() {}
virtual ~Type() {}
virtual T* allocate() const { return new T; }
virtual T* cast(void *object) const { return static_cast<T*>(object); }
};
This works just fine:
map<int, Base*> typeMap;
typeMap[1] = new Derive();
But when trying to do something like this, I got error: a value of type "Type< Derive> *" cannot be assigned to an entity of type "Type< Base> *"
map<int, Type<Base>*> typeMap;
typeMap[1] = new Type<Derive>();
Is there any chance to store something like this? I don't want any library solutions (non-opensource)
Upvotes: 0
Views: 236
Reputation: 218138
Similar to @pmr's answer but using std::tuple
#include <tuple>
#include <type_traits>
class Base{};
class Derived : public Base {};
template<std::size_t i>
struct my_map
{
private:
using myTuple = std::tuple<Base, Derived>;
public:
using type = typename std::tuple_element<i, myTuple>::type;
};
static_assert(std::is_same<Base, my_map<0>::type>::value, "bad type");
static_assert(std::is_same<Derived, my_map<1>::type>::value, "bad type");
Upvotes: 2
Reputation: 59841
Specialize a struct
on an integer for each type you would like to map.
#include <cstddef> // size_t
struct Base {};
struct Derived : Base {};
template<std::size_t i>
struct my_map;
// specialize the map (maybe shorten with a macro)
template<>
struct my_map<0> {
using type = Base;
};
template<>
struct my_map<1> {
using type = Derived;
};
// easier to use, if you compiler supports it:
template<std::size_t i>
using my_map_t = typename my_map<i>::type;
int main()
{
my_map<0>::type* b1 = new Base();
my_map<0>::type* b2 = new Derived();
my_map<1>::type* d1 = new Derived();
// my_map<1>::type* d2 = new Base(); error wrong type
// prettier
my_map_t<0>* b3 = new Base();
return 0;
}
Upvotes: 1