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

Xop*_*oph 7 c++ vector const-correctness undefined-behavior reinterpret-cast

class A
{
    std::vector<std::shared_ptr<int>> v_;
};
Run Code Online (Sandbox Code Playgroud)

现在我想添加v_使用两个公共成员函数的访问权限

std::vector<std::shared_ptr<int>> const & v() { return v_; }
Run Code Online (Sandbox Code Playgroud)

std::vector<std::shared_ptr<int const> const & v() const { TODO }
Run Code Online (Sandbox Code Playgroud)

我不能代替TODO使用return v_;,虽然.

一种选择是不返回引用而是复制.除了明显的性能损失之外,这也会使界面不那么令人满意.

另一种选择是TODO等于return reinterpret_cast<std::vector<std::shared_ptr<int const>> const &>(v_);

我的问题是,这是不确定的行为吗?或者,或者,是否有更好的选择,最好不使用reinterpret_cast

Max*_*kin 6

避免复制容器的一种方法是提供转换迭代器,在迭代引用时转换元素:

#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';
}
Run Code Online (Sandbox Code Playgroud)