Temporary read-only copy of unique_ptr
c++, c++11, shared-ptr, stdvector, unique-ptr
Solution
I'm using unique_ptr because the procedure calling all these functions is the sole owner of the objects in the vector, and the functions are just "borrowing" the objects in order to read them as input.
Since the computing functions are not owning the pointed objects, just observing their state and making computations, you should pass them a vector of observing pointers (in this case, regular raw pointers), instead of a vector of `unique_ptr`s.
Since `computeOnAllSubsets()` and `computeOnSet()` are not responsible for the lifetime of the `Scalar` objects, they should not even acquire their ownership - in other words, they should not receive the owning `unique_ptr`s.
After all, it is guaranteed by the logic of your program that those functions won't be receiving dangling references, because the owning function won't destroy its vector before it has performed all the necessary computations. This is supported directly by what you are writing:
All I want to do is make a temporary, read-only copy of a pointer, for the sole purpose of making temporary, read-only sub-vectors. Is there any way to do this?
Just pass a vector of raw pointers to your computing functions. Given a `unique_ptr`, you can get access to the encapsulated raw pointer by calling the member function `get()`:
std::unique_ptr<Scalar> pS // ... initialized somehow
Scalar* pScalar = pS.get();
As an alternative to raw pointers, you could use `std::reference_wrapper` for dispatching observing references. Especially during the process of refactoring a legacy code base where raw pointers are used for manual memory management, this would make it clear that ownership of the referenced objects belongs somewhere else.
Notice, however, that in Modern C++ a raw pointer is most often a synonym of observing pointers, so the above distinction is not really meaningful in a generalized context. The use case for which `std::reference_wrapper` is fundamental is when you want to pass objects by reference to some function template that accepts its arguments by value (`std::bind()` being a typical example).
Problem
I'm pretty new to C++11's smart pointers, and I'm trying to use them effectively in a project. In my project, I have a lot of functions that take a const reference to a `vector` of `unique_ptr`, do some computations on it, and place some results in a return parameter, like this: ``` void computeCoefficients(const vector<unique_ptr<Scalar>>& roots, vector<unique_ptr<Scalar>>& coeffs) { ... } ``` I'm using `unique_ptr` because the procedure calling all these functions is the sole owner of the objects in the `vector`, and the functions are just "borrowing" the objects in order to read them as input. Now I'm trying to write a function that does computations on different subsets of the `vector` it receives, and in order to do that it needs to have different "versions" of the `vector` containing those subsets in order to pass to yet another function that takes a `vector<unique_ptr<Scalar>>` as input. But the only way to get a subset of a vector is to make a copy of it - which is a problem because `unique_ptr`s can't be copied. I'd like the code to look something like this: ``` void computeOnSet(const vector<unique_ptr<Scalar>>& set, unique_ptr<Scalar>& output) { ... } void computeOnAllSubsets(const vector<unique_ptr<Scalar>>& set, vector<unique_ptr<Scalar>>& outputs) { for(int i = 0; i < input.size(); i++) { auto subset = vector<unique_ptr<Scalar>>(set.begin(), set.begin()+i); subset.insert(subset.end(), set.begin()+i+1, set.end(); computeOnSubset(subset, outputs.at(i)); } } ``` Of course that doesn't work. I could make it work if I replaced the `unique_ptr`s with `shared_ptr`s, but that has two problems: - It would philosophically mean that I'm sharing ownership of the set with the `computeOnSubsets` function, and I'm not; the caller is still the sole owner. (I read that `shared_ptr` means you're sharing ownership with everything that has a copy of it). - It would introduce the overhead of reference-counting, even in places where I don't need it, because it would force me to change the input parameter of all my methods to `vector<shared_ptr<Scalar>>`. All I want to do is make a temporary, read-only copy of a pointer, for the sole purpose of making temporary, read-only sub-vectors. Is there any way to do this? `weak_ptr` sounds like what I need (non-owning temporary pointer), but it can only be used with `shared_ptr`.