【发布时间】:2014-01-30 04:00:55
【问题描述】:
我目前正在尝试将 std::unique_ptr 存储在 std::unordered_map 中,但出现奇怪的编译错误。 相关代码:
#pragma once
#include "Entity.h"
#include <map>
#include <memory>
class EntityManager {
private:
typedef std::unique_ptr<Entity> EntityPtr;
typedef std::map<int, EntityPtr> EntityMap;
EntityMap map;
public:
/*
Adds an Entity
*/
void addEntity(EntityPtr);
/*
Removes an Entity by its ID
*/
void removeEntity(int id) {
map.erase(id);
}
Entity& getById(int id) {
return *map[id];
}
};
void EntityManager::addEntity(EntityPtr entity) {
if (!entity.get()) {
return;
}
map.insert(EntityMap::value_type(entity->getId(), std::move(entity)));
}
这是编译错误:
c:\program files (x86)\microsoft visual studio 12.0\vc\include\tuple(438): error C2280: 'std::unique_ptr<Entity,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)' : attempting to reference a deleted function
1> with
1> [
1> _Ty=Entity
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\memory(1486) : see declaration of 'std::unique_ptr<Entity,std::default_delete<_Ty>>::unique_ptr'
1> with
1> [
1> _Ty=Entity
1> ]
1> This diagnostic occurred in the compiler generated function 'std::pair<const _Kty,_Ty>::pair(const std::pair<const _Kty,_Ty> &)'
1> with
1> [
1> _Kty=int
1> , _Ty=EntityManager::EntityPtr
1> ]
【问题讨论】:
-
使用 clang++ 3.5 编译良好span>
-
我不知道编译时错误,但是这个调用:
map.insert(EntityMap::value_type(entity->getId(), std::move(entity)))无论如何都是不安全的,因为未指定将entity移动到函数的参数之前还是之后发生entity->getId()的评价。将getId()分配给一个临时对象以传递给函数。 -
这很可能是 MSVC 提供的
std库的问题。查找错误报告,或设置ssccr.org 并提交一份? -
您可以尝试:
map.insert(std::move(std::make_pair(entity->getId(), std::move(entity))));或尝试使用std::forward。我以前有过这个错误。我不记得我是如何在 VS2012 中解决它的,但我确定它涉及向前或移动。另一个选择是在地图中插入一个 nullptr。然后使用索引运算符,将分配移动到它。 -
它通过右值引用传递,它将所有权从临时转移到地图。这就是移动构造函数的用途。例如:
std::unique_ptr<int> up(new int); std::unique_ptr<int> up2(std::move(up));int 指针的所有权从up转移到up2
标签: c++ visual-studio-2012 c++11 unique-ptr