简体   繁体   English

将shared_ptr的向量转换为shared_ptr的向量为const

[英]Turning vector of shared_ptr into vector of shared_ptr to const

Let

class A
{
    std::vector<std::shared_ptr<int>> v_;
};

Now I'd like to add access to v_ using two public member functions 现在我想使用两个公共成员函数添加对v_访问

std::vector<std::shared_ptr<int>> const & v() { return v_; }

and

std::vector<std::shared_ptr<int const> const & v() const { TODO }

I cannot replace TODO with return v_; 我不能用return v_;替换TODO return v_; though. 虽然。

One option would be to not return a reference but a copy. 一种选择是不返回引用而是复制。 Apart from the obvious performance penalty, this would also make the interface somewhat less desirable. 除了明显的性能损失之外,这也会使界面不那么令人满意。

Another option is to make TODO equal to return reinterpret_cast<std::vector<std::shared_ptr<int const>> const &>(v_); 另一种选择是使TODO等于return reinterpret_cast<std::vector<std::shared_ptr<int const>> const &>(v_);

My question is, is this undefined behavior? 我的问题是,这是不确定的行为吗? Or, alternatively, is there a better option, preferably without using reinterpret_cast ? 或者,是否有更好的选择,最好不使用reinterpret_cast

A way to avoid copying the container is to provide transform iterators that transform the element on dereference: 避免复制容器的一种方法是提供转换迭代器,在迭代引用时转换元素:

#include <vector>
#include <memory>
#include <boost/iterator/transform_iterator.hpp>

class A
{
    std::vector<std::shared_ptr<int> > v_;

    struct Transform
    {
        template<class T>
        std::shared_ptr<T const> operator()(std::shared_ptr<T> const& p) const {
            return p;
        }
    };

public:

    A() : v_{std::make_shared<int>(1), std::make_shared<int>(2)} {}

    using Iterator = boost::transform_iterator<Transform, std::vector<std::shared_ptr<int> >::const_iterator>;

    Iterator begin() const { return Iterator{v_.begin()}; }
    Iterator end() const { return Iterator{v_.end()}; }

};

int main() {
    A a;
    // Range access.
    for(auto const& x : a)
        std::cout << *x << '\n';
    // Indexed access.
    auto iterator_to_second_element = a.begin() + 1;
    std::cout << **iterator_to_second_element << '\n';
}

Putting aside the discussion of whether or not you should return a reference to a member... 暂且讨论你是否应该返回对成员的引用......

std::vector already propagates its own const qualifier to the references, pointee's and iterators it returns. std::vector已经将自己的const限定符传播给它返回的引用,指针和迭代器。 The only hurdle is making it propagate further to the pointee type of the std::shared_ptr . 唯一的障碍是让它进一步传播到std::shared_ptr的指针类型。 You can use a class like std::experimental::propagate_const (that will hopefully be standardized) to facilitate that. 你可以使用像std::experimental::propagate_const这样的类(希望能够标准化)来促进这一点。 It will do as its name implies, for any pointer or pointer-like object it wraps. 它就像它的名字所暗示的那样,对于它包装的任何指针或指针式对象。

class A
{
    using ptr_type = std::experimental::propagate_const<std::shared_ptr<int>>;
    std::vector<ptr_type> v_;
};

Thus TODO can become return v_; 因此TODO可以成为return v_; , and any access to the pointees (like in the range-based for you wish to support) will preserve const-ness. ,任何对指定者的访问(如在你希望支持的范围内)都将保持一致性。

Only caveat is that it's a moveable only type, so copying out an element of the vector will require a bit more work (for instance, by calling std::experimental::get_underlying ) with the element type of the vector itself. 唯一需要注意的是它只是一个可移动的类型,因此复制一个向量元素需要更多的工作(例如,通过调用std::experimental::get_underlying )和向量本身的元素类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 shared_ptr到shared_ptr的向量 - shared_ptr to vector of shared_ptr 带矢量的shared_ptr - shared_ptr with vector 是否可以传递矢量 <shared_ptr<T> &gt;到const向量 <shared_ptr<const T> &gt;&参数? - Is it possible to pass a vector<shared_ptr<T>> to a const vector<shared_ptr<const T>>& parameter? 将带有非 const 元素的 shared_ptr 向量转换为带有 const 元素的 shared_ptr 向量 - transform vector of shared_ptr with non const elements to vector of shared_ptr with const elements shared_ptr <T>到shared_ptr <T const>,vector <T>到vector <T const> - shared_ptr<T> to shared_ptr<T const> and vector<T> to vector<T const> 矢量的隐式转换 <shared_ptr<Foo> &gt;向量 <shared_ptr<const Foo> &gt; - Implicit conversion of vector<shared_ptr<Foo> > to vector<shared_ptr<const Foo> > vector <shared_ptr <T >>和vector <shared_ptr <const T >>之间的高效转换 - Efficient conversion between vector<shared_ptr<T>> and vector<shared_ptr<const T>> 将现有的shared_ptr追加到shared_ptr的向量 - Appending an existing shared_ptr to a vector of shared_ptr 正在使用 std::vector&lt; std::shared_ptr<const T> &gt; 反模式? - Is using std::vector< std::shared_ptr<const T> > an antipattern? 替换std :: vector中的shared_ptr元素 - Replacing shared_ptr elements in std::vector
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM