【问题标题】:Using a template class in STL containers在 STL 容器中使用模板类
【发布时间】:2019-04-03 09:28:34
【问题描述】:

如果我有一个模板类,我想用不同的数据类型进行实例化:

template <typename T>
class A {
  T value;
  // ...
};

我还想在标准模板库容器中使用这个类的对象(比如vector)。

在我的理解中,编译器不会接受创建A 对象的向量,因为A&lt;int&gt; 和A&lt;char&gt; 实际上是不同的类型,我不能将它们放在同一个向量中。

我找到的解决方法是创建一个基类、一个派生模板类和一个基类指针向量。

class ABase {
  // ...
};

template <typename T>
class ADerived : public ABase{
  T value;
  // ...
};

std::vector<BaseA*> mySuperVector;

我开始尝试使用模板以获得更好的理解,我想知道是否有更好的解决方案。我上面的解决方法也让我很头疼,因为我担心在某些时候类型转换是不可避免的。

【问题讨论】:

    标签: c++ templates inheritance stl generic-programming


    【解决方案1】:

    需要对派生类型进行类型转换与派生类型是类模板的实例化无关,这是一个设计问题。也许您需要虚拟函数或多个容器。

    否则,您的解决方案很好,但如果容器应该拥有包含的对象,请切换到 std::unique_ptr。

    【讨论】:

    • 关于类型转换是一个设计问题,您是绝对正确的。我还没有,但感觉不对,因为继承是强制的,所以我可以将模板类放在同一个容器中。变通办法的强制设计通常会导致设计问题。另外添加额外的继承层似乎很浪费。 (我正在研究嵌入式系统)
    • @lulijeta 您将对象放在同质容器中,前提是它们可以根据您的需要以相同的方式处理。如果不是这样,那么单个容器不会切割它。
    • 我猜你是对的。它们绝对可以以同样的方式处理。
    【解决方案2】:

    模板是一种编译时代码生成结构。如果你在编译时需要一个异构的对象容器,那么你可以使用std::tuple:

    std::tuple my_tuple{A<int>{}, A<char>{}, A<double>{}};
    

    如果您在运行时需要一个异构的对象容器,您确实需要某种多态性。使用带有virtual 方法的基类是一个有效的选项。如果你事先知道你的对象可以选择的所有类型,你也可以使用std::variant:

    using my_a = std::variant<A<int>, A<char>, A<double>>;
    std::vector<my_a> vec;
    

    在这种情况下,my_a 在任何给定时间都可以是A&lt;int&gt;、A&lt;char&gt; 或A&lt;double&gt;。活动的替代品可以在运行时改变。

    【讨论】:

    • 谢谢@Vittorio Romeo 我从来没有一个合理的元组和变体用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多