【问题标题】:Conversion from STL vector of subclass to vector of base class子类STL向量到基类向量的转换
【发布时间】:2011-08-07 13:38:45
【问题描述】:

我想知道是否可以将派生类值的向量转换为基类值的向量。具体来说,我希望能够将基类对象的向量传递给其形式参数采用基类向量的函数。似乎无法直接使用,因为以下代码示例会产生错误(使用 g++):

#include <vector>

class A {
};

class B : public A {
};


void function(std::vector<A> objs) {
}

int main(int argc, char **argv) {
    std::vector<B> objs_b;
    objs_b.push_back(B());
    function(objs_b);
}

test.cc:16: 错误:从 'std::vector >' 转换为非标量类型 'std::vector >'请求

我希望能够调用函数,而无需定义具有 A 类型元素的新向量、插入 B 类型元素或更改为指针向量。

【问题讨论】:

  • 使用模板怎么样?
  • @GWW 是的,模板就是答案,谢谢。
  • 如何将指针传递给向量。我没有对向量做太多的工作,但你不能将指针传递给向量。就这么简单吗?
  • baash:没那么容易,抱歉。矢量* 不能转换为矢量*,就像矢量 不是矢量一样。
  • “我希望能够调用函数,而不必定义具有 A 类型元素的新向量,插入我的 B 类型元素”。重要提示:不要这样做,这将不起作用。 vector&lt;A&gt; 的元素的运行时类型始终为 A。如果您尝试将子类对象插入到向量中,它将被切片为A

标签: c++ oop stl vector polymorphism


【解决方案1】:

不,不是。 vector&lt;B&gt; 不是从vector&lt;A&gt; 派生的,尽管B 是从A 派生的。您将不得不以某种方式更改您的功能。

一种更惯用的 C++ 方法可能是对其进行模板化并使其采用一对迭代器 - 这就是各种标准库函数(&lt;algorithm&gt; 等)以这种方式工作的原因,因为它将算法的实现与它正在运行的东西。

【讨论】:

  • 在这种情况下如何实现模板?
【解决方案2】:

有时有办法解决这个问题。在 Boost 和他们拥有或使用的一些模板元编程包中抢夺一宝。具体来说,我会查看is_base_of 用于这些目的以及部分模板专业化。

例如,如果你想做一些模板魔术:

template<typename T, bool Allowed>
struct TemplateVectorCode;

您对模板类进行了前向声明。然后你用一个“真”的布尔值进行特化:

template<typename T> struct TemplateVectorCode<T, true>{
    void operator(const std::vector<T>& myVector) const{ //definition in here }
};

最后,您将它与is_base_of 一起使用,以仅以下列方式实例化模板仿函数的实例:

template<typename T, typename Base>
struct MyFunction : TemplateVectorCode<T, boost::is_base_of<Base,T>::value>{
};

需要注意的重要一点是,由于我们没有定义 TemplateVectorCode&lt;T, false&gt;,如果您尝试将仿函数与不是从类型 V 派生的类类型 T 一起使用,编译器将引发编译错误.这意味着您可以在一个地方使用相同的代码,而无需编写多个版本。

(如果我搞砸了部分模板专业化,请有人编辑它。我要睡觉了。)

【讨论】:

    【解决方案3】:

    以下是如何使用 C++14 中的模板使您的函数接受给定类型(在本例中为 A 类)的任何子类的标准向量。

    class A {};
    class B : public A {};
    
    template<typename T, std::enable_if_t<std::is_base_of_v<A, T>, bool> = true>
    void function(const std::vector<T>& vec) {
        // implemenation
    }
    
    std::vector<A> vec_a;
    std::vector<B> vec_b;
    function(vec_a); // ok
    function(vec_b); // ok
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-13
      • 2020-08-30
      • 2021-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多