transform vector of shared_ptr with non const elements to vector of shared_ptr with const elements

Viewed 52

I have a class A containing a vector of shared_ptr<B>. I implemented a getter to this vector. In some cases, it would be nice to ensure that the content in B does not change (make B read only or a const reference).

If I would not have used vector<shared_ptr<B>> but rather vector<B> I could simply write two getters, one returning a const reference (read only), and one returning a reference only (manipulation possible). #

Is there a way to do the same thing with a vector<shared_ptr<B>>?

Maybe it is easier to understand the problem in this code:

#include <vector>
#include <memory>
using namespace std;

class B{
public:
    explicit B(int i) : i_{i} {}
    void set_i(int i){i_ = i;}
private:
    int i_ = 0;
};

class A{
public:
    const vector<shared_ptr<B>> &get_vb(){return vb;}
    // const vector<shared_ptr<const B>> &get_vb_const(){return vb;} // I would like to return a const vector with const elements in some cases 
private:
    vector<shared_ptr<B>> vb{make_shared<B>(1), make_shared<B>(10), make_shared<B>(100)};
};

int main() {
    A a;
    const auto &vb = a.get_vb();
    vb[0]->set_i(2);
    
    // const auto &vb_const = a.get_vb_const(); // somehow I would like to gain this vector without being able to modify the elements
    // vb_const[0]->set_i(2); // should throw error
    
    return 0;
}
2 Answers

You need to construct a new vector with the desired elements:

    const vector<shared_ptr<const B>> get_vb_const() const { 
        return vector<shared_ptr<const B> > {vb.cbegin(), vb.cend()};
    }

Note that the function doesn't return a reference now because we are creating a temporary and returning it.

transform vector of shared_ptr with non const elements to vector of shared_ptr with const elements

You can use the constructor of vector that accepts a pair of iterators to perform the conversion.

You can avoid the overhead of allocating and copying a vector by implementing a custom const iterator for your class.

Related