将 vector<shared_pt<T>> 复制到 vector<shared_ptr<const T>>(不同情况)C++

Copying vector<shared_pt<T>> to vector<shared_ptr<const T>> (different cases) C++

本文关键字:lt gt vector shared 情况 C++ pt 复制 ptr const      更新时间:2023-10-16

我有一个:

std::vector<std::shared_ptr<T>>

我想复制到

std::vector<std::shared_ptr<const T>>

现在我注意到,如果我这样做:

class A
{
public:
    A(const std::vector<std::shared_ptr<int>>& list) : internalList(list.begin(), list.end()) {}
    std::vector<std::shared_ptr<const int>> internalList;
};

它编译得很好(clang++std==c++14(,但如果我编译了:

class A
{
public:
    A(const std::vector<std::shared_ptr<int>>& list) : internalList(list) {}
    std::vector<std::shared_ptr<const int>> internalList;
};

我觉得奇怪的是,当我使用复制构造函数时,它不起作用,因为它无法计算从非常量到常量的转换?

xxxx.cpp:672:56: error: no matching constructor for initialization of 'std::vector<std::shared_ptr<const int> >'

有人能解释一下为什么吗?我这样做的方式(在构造函数中使用迭代器(是否是最好的解决方案?

如果std::vector提供了一个转换构造函数:,您的代码就可以工作

template<class T, class A = std::allocator<T>>
class vector {
public:
    template<class T1, class A1>
    explicit vector(const vector<T1, A1>& other)
        : vector(other.begin(), other.end())
    {}
    ...
};

但是,在每个标准库容器中都有这样一个构造函数并不会增加太多价值,因为通过引入更通用的container_cast实用程序(例如,请参阅此答案(,可以实现几乎相同的效果。然后你可以写:

class A
{
public:
    A(const std::vector<std::shared_ptr<int>>& list) : internalList(container_cast(list)) {}
    std::vector<std::shared_ptr<const int>> internalList;
};

首先,用不同类型实例化的类模板是完全不同的类型。那么std::shared_ptr<int>std::shared_ptr<const int>是完全不同的类型,std::vector<std::shared_ptr<int>>std::vector<std::shared_ptr<const int>>也是不同的类型并且不能相互转换。

根据std::vector的构造函数,复制构造函数(第五个(以一个类型相同的std::vector作为其参数。这意味着对于std::vector<std::shared_ptr<const int>>,它不能取std::vector<std::shared_ptr<int>>,后者不能隐式转换为std::vector<std::shared_ptr<const int>>

另一方面,采用迭代器范围的构造函数(第四个(是函数模板,迭代器的类型是模板参数,不必是指向同一类型的迭代器。它可以是指向其他类型的迭代器,如果这个类型可以用来构造向量的话。std::shared_ptr<int>可以用来构建std::shared_ptr<const int>,那就好了。

请注意,std::shared_ptr具有复制/移动构造函数模板,这些模板可以使用具有不同元素类型的std::shared_ptr作为参数。(而std::vector没有。(