Reputation: 470
This is more of a best practices type of question. Please assume that there are no issues with correctness.
Is it okay to pass around a vector of unique_ptrs by reference between functions in the same class? I want to do this to apply some changes to all the elements in the vector.
Related reason for confusion: isocpp guidelines
Example: If I have a() calls b() calls c(), but some steps in b() should be done to only the first element in the vector, but I want to apply c() to all elements. Example:
a(){
vector<unique_ptr<blah>> stuff;
...
b(stuff);
}
b(vector<unique_ptr<blah>>& stuff){
auto result = do_stuff_to(stuff.front().get());
c(stuff, result);
}
c(vector<unique_ptr<blah>>& stuff, some_type result){
...
}
What would be a nicer/cleaner way? Thank you!
Edit:
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
struct Stuff{
int a;
};
void c(vector<unique_ptr<Stuff>>& stuffs){
for(const auto& stuff: stuffs){
cout<<"c:"<< stuff->a<<endl;
}
}
void b(vector<unique_ptr<Stuff>>& stuffs){
cout<<"b:"<< stuffs.front()->a<<endl;
c(stuffs);
}
void a(){
vector<unique_ptr<Stuff>> stuffs;
stuffs.push_back(std::make_unique<Stuff>());
stuffs.push_back(std::make_unique<Stuff>());
b(stuffs);
}
int main()
{
a();
return 0;
}
Upvotes: 0
Views: 214
Reputation: 217398
Whereas from std::unique_ptr<myType>
, we can easily use /*const*/ myType*
or /*const*/ myType&
when no ownership transfer is involved.
There are no trivial/simple types to represent the equivalent for range (std::vector<std::unique_ptr<myType>>
):
std::vector<myType*>
need extra vector.my_vec | ranges::transform([](std::unique_ptr<myType>& ptr){ return ptr.get(); })
is not a trivial type to write. Template or auto
can still be used, but doesn't explain intent, we might have to add c++20 concepts to clarify it. But using template for "fixed" type has also its cons.I don't see a winner from the 3 options.
Upvotes: 4