【问题标题】:Copying from vector of derived class to vector of base class从派生类的向量复制到基类的向量
【发布时间】:2021-09-27 19:10:58
【问题描述】:

我正在寻找将派生类的向量复制到基类的向量的最简单方法,而无需逐个元素地进行。如何解决以下问题以使其正常工作?

#include <vector>
#include <iostream>

struct A {
    A( int a) : a(a) {}
    int a;
};

struct B : public A {
    B (int a, int b) : A (a), b(b) {}
    int b;
};

int main() {
    std::vector<B> vb { B{1,2}, B{3,4}};
    std::vector<A> va = vb;
    for (const auto& item : va) {
        std::cout << item.a << " ";
    }
    std::cout << std::endl;
    return 0;
}

现在我从 g++ 收到以下错误消息

error: conversion from ‘vector<B>’ to non-scalar type ‘vector<A>’ requested
   16 |     std::vector<A> va = vb;

【问题讨论】:

    标签: c++ stl


    【解决方案1】:

    std::vector&lt;A&gt;不能直接从std::vector&lt;B&gt;转换,它们本质上是两个独立的类型。

    您可以使用vb 的迭代器初始化va

    std::vector<A> va { vb.begin(), vb.end() };
    

    请注意,va 的元素将被切片复制。

    【讨论】:

    • 有趣。如果没有 struct A 构造,例如 A(const B& b) : a(b.a) { } 怎么可能自动转换?
    • @DDukDDak99 A 的复制构造函数采用const A&amp;,而B 可以绑定到const A&amp;,因为它是A 的派生类。结果B 可以隐式转换(切片复制)为A(通过A 的复制构造函数)。
    • 哦。正确的。我忘了 struct B 是派生的。
    • 最初我虽然继承会允许一些捷径,但可能比它的价值更麻烦。因此,我发布了一个使用合成的答案。
    【解决方案2】:

    如果你更喜欢组合而不是继承,你可以使用:

    #include <vector>
    #include <iostream>
    #include <algorithm>
    
    struct A {
        int a;
    };
    
    struct B {
        A a;
        int b;
    };
    
    int main() {
        std::vector<B> vb { {1 ,2},{3, 4} };
        std::vector<A> va;
        std::transform(vb.begin(), vb.end(), std::back_inserter(va), 
                [](const B& b) -> A { return b.a; } );
        for (const auto& item : va) {
            std::cout << item.a << " ";
        }
        std::cout << std::endl;
        return 0;
    }
    

    【讨论】:

    • 尽管 lambdas 很酷,但我更喜欢 std::mem_fn(&amp;B::a) 在这种情况下,因为它更短且更通用。
    猜你喜欢
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    • 2013-03-28
    • 1970-01-01
    • 1970-01-01
    • 2020-08-30
    • 1970-01-01
    • 2017-02-06
    相关资源
    最近更新 更多