Search code examples
c++c++17smart-pointers

keeping shared_ptr use_count() at 1


I was unable to find a similar question to this one, please direct me to one if I missed it! I am experimenting with smart pointers, and came to this scenario where I would like to keep the value returned by use_count() in a shared_ptr object to 1 (to practice optimizing code). Here is a snippet I am working with:

#include <iostream>
#include <memory>
#include <vector>

// testFunc: displays the use_count of each shared ptr in the list
void testFunc(const std::vector<std::shared_ptr<int>> &list) {
    // reference each shared ptr in the list and display their use_count
    for (auto &elem : list) {
        std::cout << elem.use_count() << std::endl;
    }   
} // testFunc()

int main() {
    // allocate shared ptr instance of an int
    auto sharedTest = std::make_shared<int>(11);

    // allocate another shared ptr instance of another int
    auto anotherSharedTest = std::make_shared<int>(22);

    // use std::move to prevent another copy of the shared ptrs from being created
    testFunc({ std::move(sharedTest), std::move(anotherSharedTest) }); 

    return 0;
} // main()

The output by this program is

2
2

since the use_count of both shared ptrs is 2. Can anyone show me why I cannot keep them at 1? I suspect that "passing" the vector to testFunc is creating a copy of each shared ptr when the entire vector is being passed, however this surprises me since I am passing the vector by reference. Any input is greatly appreciated!


Solution

  • The problem is the temporary initializer_list<shared_ptr> keeps a copy of the elements, and it lives until the end of the full-expression (the ;).

    There isn't much you can do, an initializer_list always stores its elements by copy.

    As a workaround, you can construct the vector beforehand:

    std::vector<std::shared_ptr<int>> list{std::move(sharedTest), std::move(anotherSharedTest)};
    testFunc(list);
    

    Should print 1 1.