插入无序映射将共享ptr变为null
Insert into a unordered map changes the share ptr to null
在下面的示例中,从第一个map中取出值并插入到第二个map后,共享ptr变为空。甚至析构函数也没有被调用。我不明白到底是怎么回事
#include <iostream>
#include <memory>
#include <unordered_map>
class Test
{
public:
Test(){}
~Test(){}
int test;
};
typedef std::shared_ptr<Test> Test_ptr;
typedef std::unordered_map<std::string, Test_ptr> TestMap;
int main()
{
TestMap map1, map2;
std::string key("abc");
Test_ptr ptr(new Test);
map1.insert(TestMap::value_type(key, ptr));
TestMap::iterator iter = map1.find(key);
if (iter != map1.end())
{
map2.insert(*iter);
if (iter->second == nullptr)
{
std::cout << "after insert the shared ptr becomes null" << std::endl;
}
}
}
c++ -std=c++11 testsharedptr.cpp - 0 testsharedptr
gcc version 4.8.1
我无法使用GCC 4.9.2重现这个问题。但是,我能够使用GCC 4.8.1重现它。
根本原因是libstdc++实现以下std::unordered_map::insert()
过载的错误:
template< class P >
std::pair<iterator,bool> insert( P&& value );
GCC 4.8.1的实现是
template<typename _Pair, typename = typename std::enable_if<std::is_constructible<value_type, _Pair&&>::value>::type>
std::pair<iterator, bool>
insert(_Pair&& __x)
{ return _M_h.insert(std::move(__x)); }
而GCC 4.9.2的实现是
template<typename _Pair, typename = typename std::enable_if<std::is_constructible<value_type, _Pair&&>::value>::type>
std::pair<iterator, bool>
insert(_Pair&& __x)
{ return _M_h.insert(std::forward<_Pair>(__x)); }
在GCC 4.8.1的情况下,您传递的映射项被移动到map2
而不是复制。因此,作为移动的副作用,std::shared_ptr
从map1
被设置为nullptr
。
如果可能的话,我建议升级到GCC 4.8.2或更高版本,其中这个错误已经修复。
如果您无法升级,使用const_iterator
将产生预期的行为:
TestMap::const_iterator iter = map1.find(key);
通过使用const_iterator
,您将强制调用此重载:
std::pair<iterator,bool> insert( const value_type& value );
相关文章:
- CLANG 编译器 说:变量"PTR"可能未初始化
- 在以唯一ptr为值的C++映射中,动态内存何时会被销毁
- 将 ptr 传递给 ptr 到 A 作为参数传递给 A 的函数是不好的做法吗?
- Arduino-C++ bool 不会从 false 变为 true
- 为共享 ptr 向量实现复制 c'tor?
- 字符和整数中 **(ptr+1) 的值差异
- C++:在不中断共享的情况下通过引用传递共享 PTR?
- 代码精简版页面变为空白
- 如何将派生类从基 ptr 分配给 nlohmann::json
- 引用 std::shared:ptr 以避免引用计数
- 帧缓冲纹理变为白色(片段着色器不会影响它)
- 为什么我不能在不进行任何转换的情况下将浮点数放入任何类型的 ptr 中?
- 在调用函数时,ptr** 和 ptr*& 之间是否有区别,或者首选C++?
- 另一种类型的智能ptr,比如具有弱refs的unique_ptr
- 尝试打印出 *ptr++ 的值,以了解它是如何工作的
- 如何控制共享 ptr 引用计数?
- 此数组中的某些值无缘无故变为零 (0)
- 使用指针编译代码后,.cpp文件将变为随机字符
- 使用 std::smatch 作为返回类型将导致匹配器变为" 00 00 00 00 00 00 00"
- 插入无序映射将共享ptr变为null