Pass std::shared_ptr by value or const ref and then store it in the container?


sl

Consider the following vector:

std::vector<std::shared_ptr<X>> myVector;

and the following two functions that add a given element to a vector:

void foo1(std::shared_ptr<X> x)
{
    myVector.push_back(x);
}

void foo2(const std::shared_ptr<X>& x)
{
    myVector.push_back(x);
}

As far as I know, both functions push shared_ptrinto Xthe vector, thereby increasing the reference count X. The first function causes additional increments and decrements of the reference count, but this is unnecessary.

Is my understanding correct? So, is the second option advisable?

101010

When foo1you pass parameters by value (i.e. shared pointers). Therefore, the copy constructor will be induced (ie, the reference counter will be incremented, and then down when the std::shared_ptr<X>local copy destructor is called ).}foo1

Before foo2you pass a parameter (ie, a shared pointer) to the constreference. Therefore, you are passing a qualified alias of the constoriginal object (ie, the reference counter is not incremented).

You can also see this in the following example:

struct X {};

void foo1(std::shared_ptr<X> x) { 
  std::cout << "count in foo1(): " << x.use_count() << std::endl;
}

void foo2(const std::shared_ptr<X>& x) {
  std::cout << "count in foo2(): " << x.use_count() << std::endl;
}

int main() {
  std::shared_ptr<X> x(new X);
  std::cout << "count in main(): " << x.use_count() << std::endl;
  foo1(x);
  foo2(x);
}

output:

count in main(): 1
count in foo1(): 2
count in foo2(): 1

As you can see foo1, the number of distinct shared_ptr instances is 2. This is the original instance shared_ptrdefined in mainand a copy foo1in . while foo2still 1 in the ref counter.

So your reasoning is correct.

Related


const std::shared_ptr & const correctness

Sam Martens Suppose I have a class class K { public: int k = 0; void Change() { k++; } void None() const { std::cout << "None \n"; } }; Why is it perfectly fine to use a non const method on a const reference li

const std::shared_ptr & const correctness

Sam Martens Suppose I have a class class K { public: int k = 0; void Change() { k++; } void None() const { std::cout << "None \n"; } }; Why is it perfectly fine to use a non const method on a const reference li

const std::shared_ptr & const correctness

Sam Martens Suppose I have a class class K { public: int k = 0; void Change() { k++; } void None() const { std::cout << "None \n"; } }; Why is it perfectly fine to use a non const method on a const reference li

const std::shared_ptr & const correctness

Sam Martens Suppose I have a class class K { public: int k = 0; void Change() { k++; } void None() const { std::cout << "None \n"; } }; Why is it perfectly fine to use a non const method on a const reference li

const std::shared_ptr & const correctness

Sam Martens Suppose I have a class class K { public: int k = 0; void Change() { k++; } void None() const { std::cout << "None \n"; } }; Why is it perfectly fine to use a non const method on a const reference li

const std::shared_ptr & const correctness

Sam Martens Suppose I have a class class K { public: int k = 0; void Change() { k++; } void None() const { std::cout << "None \n"; } }; Why is it perfectly fine to use a non const method on a const reference li

Pass pointer by value or const ref?

Barry In short, is it better to pass pointers by value or const reference? I wrote a simple function to explore: void foo(int* v) { std::cout << *v << endl; } and void foo(int* const& v) { std::cout << *v << endl; } I tried looking at the generated assembly,