nahzor
nahzor

Reputation: 470

Passing vector of unique_ptrs by reference

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

Answers (1)

Jarod42
Jarod42

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>>):

  • transforming into std::vector<myType*> need extra vector.
  • the lazy/range version 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

Related Questions