【问题标题】:Using derived class in Template and storing it into vector of base class在模板中使用派生类并将其存储到基类的向量中
【发布时间】:2014-07-17 09:23:19
【问题描述】:

我正在尝试使用 std::map 和存储类型的 Type 类在 C++ 中创建类型映射。然后有一个基类 Base 和一些我想要存储的派生类。

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); }
};

这很好用:

map<int, Base*> typeMap;
typeMap[1] = new Derive();

但是当试图做这样的事情时,我得到了错误:“Type *”类型的值不能分配给“Type *”类型的实体

map<int, Type<Base>*> typeMap;
typeMap[1] = new Type<Derive>();

有没有机会存储这样的东西?我不想要任何库解决方案(非开源)

【问题讨论】:

  • 您知道您将int 映射到Type&lt;Base&gt;* 类型的对象,而不是将int 映射到实际类型。
  • 整个事情需要是运行时构造还是编译时间可以?
  • 编译时间没问题@pmr
  • Type&lt;Base*&gt;Type&lt;Derived*&gt; 不可兑换。
  • @Gelidus I don't want any library solutions 好吧,你可以得到一个库,看看他们是如何实现你所要求的。想法没有版权,至少理论上没有。

标签: c++ oop templates inheritance map


【解决方案1】:

类似于@pmr 的回答,但使用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");

【讨论】:

  • 很好,但是您不能在任意位置扩展 std::tuple。根据您的用例,这可能是需要的。不过我喜欢你的解决方案。
【解决方案2】:

struct 指定为您要映射的每种类型的整数。

#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;
}

【讨论】:

  • 如何使用它来创建对象的新实例,例如在地图 上使用该类型?
  • my_map&lt;0&gt;::type()会调用0映射到的类型的构造函数,也可以先获取一个typedef my_map&lt;0&gt;::type Name,然后使用Name()
猜你喜欢
  • 1970-01-01
  • 2018-09-17
  • 2021-11-22
  • 2013-03-27
  • 2012-02-05
  • 2023-03-28
  • 1970-01-01
相关资源
最近更新 更多