I'm creating a program which has a map containing shared_ptr's. And when I try to find an element in it with std::find_if
, the reference count of the shared_ptr increases. Example:
#include <iostream>
#include <memory>
#include <map>
#include <algorithm>
int main(void)
{
std::map<int, std::shared_ptr<int>> map;
map[1] = std::make_shared<int>(3);
map[2] = std::make_shared<int>(5);
map[4] = std::make_shared<int>(-2);
auto it = std::find_if(map.begin(), map.end(),
[](const std::pair<int, std::shared_ptr<int>> &elem) {
std::cout << "find_if: " << elem.second.use_count() << std::endl;
return *elem.second == 5;
});
std::cout << "main: " << it->second.use_count() << std::endl;
}
With this code I get the output of
find_if: 2
find_if: 2
main: 1
and I'm not sure if the reference count increase is proper behaviour.
I'm using Visual Studio 2017.
The problem is the type of the parameter of your lambda
const std::pair<int, std::shared_ptr<int>> &
...this does not correspond to std::map<<int, std::shared_ptr<int>>>::value_type
(you are missing the const
for the key type).
Thus, in order to call your lambda, a temporary object of type std::pair<int, std::shared_ptr<int>>
has to be constructed from the std::pair<const int, std::shared_ptr<int>>
stored in the std::map
.
When this object is constructed, the shared_ptr
is copied, so its reference counter has to be incremented.
If you change the type of the argument to
const std::pair<const int, std::shared_ptr<int>> &
...the problem disapears. You could also use const auto&
instead of the full type here.
1 If you use a non-const
reference here, you'll get a compiler error because you cannot initialize a reference of type std::pair<int, std::shared_ptr<int>>
from a std::pair<const int, std::shared_ptr<int>>
, but a const
-reference allow a temporary to be used instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With