在包含shared_ptr的地图上使用find_if会增加引用计数

IlC*_*ano 4 c++

我正在创建一个程序,其中包含一个包含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;
}
Run Code Online (Sandbox Code Playgroud)

有了这段代码,我得到的输出

find_if: 2
find_if: 2
main: 1
Run Code Online (Sandbox Code Playgroud)

而且我不确定参考计数的增加是否正确。

我正在使用Visual Studio 2017。

Hol*_*olt 7

问题是您的lambda参数的类型

const std::pair<int, std::shared_ptr<int>> &
Run Code Online (Sandbox Code Playgroud)

...这不对应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>> &
Run Code Online (Sandbox Code Playgroud)

问题消失了 您也可以const auto&在这里使用而不是完整类型。

1如果使用非const此引用,你会得到一个编译器错误,因为你无法初始化类型的参考std::pair<int, std::shared_ptr<int>>std::pair<const int, std::shared_ptr<int>>,而是const引用允许临时用于代替。