我正在创建一个程序,该程序的地图包含shared_ptr。当我尝试使用std::find_if
在其中查找元素时,shared_ptr的引用计数增加了。示例:
#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;
}
使用此代码,我得到的输出
find_if: 2
find_if: 2
main: 1
我不确定引用计数的增加是否正确。
我正在使用Visual Studio 2017。
答案 0 :(得分:7)
问题是您的lambda参数的类型
const std::pair<int, std::shared_ptr<int>> &
...这与std::map<<int, std::shared_ptr<int>>>::value_type
不对应(密钥类型缺少const
)。
因此,要调用您的lambda,必须根据存储在std::pair<int, std::shared_ptr<int>>
中的std::pair<const int, std::shared_ptr<int>>
构造一个std::map
类型的临时对象。
构造此对象时,将复制shared_ptr
,因此必须增加其引用计数器。
如果将参数类型更改为
const std::pair<const int, std::shared_ptr<int>> &
...问题消失了。您也可以在此处使用const auto&
代替完整类型。
1 如果在此处使用非const
引用,则会出现编译器错误,因为无法从a初始化类型为std::pair<int, std::shared_ptr<int>>
的引用std::pair<const int, std::shared_ptr<int>>
,但使用const
引用可以代替使用临时文件。