在映射中使用std::unique_ptr作为键

Using std::unique_ptr inside a map as a key

本文关键字:ptr unique std 映射      更新时间:2023-10-16

我使用的是Visual Studio 2012。我有一张像这样的地图:

std::map<std::string,std::map<std::unique_ptr<sf::Sound>,std::unique_ptr<sf::SoundBuffer>>> listSoundContainer;

我正试图插入这样的数据:

std::unique_ptr<sf::SoundBuffer> soundBuffer(new sf::SoundBuffer());
if (soundBuffer->loadFromFile("assets/sound/" + _fileName) != false)
{
std::unique_ptr<sf::Sound> sound(new sf::Sound(*soundBuffer));
typedef std::map<std::unique_ptr<sf::Sound>, std::unique_ptr<sf::SoundBuffer>> innerMap;
listSoundContainer[_fileName].insert(innerMap::value_type(std::move(sound), std::move(soundBuffer)));               
}

我在编译时得到以下错误:

microsoft visual studio 11.0\vc\include\utility(182):错误C2248:'std::unique_ptr&lt_Ty>::unique_ptr':无法访问私有成员在类"std::unique_ptr&lt_Ty>'1>与1>
[1>_Ty=sf::声音1>]1>c:\programfiles(x86)\microsoft visual studio 11.0\vc\include\memory(1447):请参阅'std::unique_ptr<的声明_Ty>::unique_ptr'1>与1>[1]_Ty=sf::声音1>]1>c:\programfiles(x86)\microsoft visual studio 11.0\vc\include\xmemory0(617):请参阅对函数模板实例化的引用'std::对&lt_Ty1,_Ty2>::pair(std::pair<_Ty1,_Ty2>&&,void**)'正在用1>[1>
_Ty1=const std::unique_ptr,1>_Ty2=std::unique_ptr、1>_Kty=std:::unique _ptr,1>_Ty=std::unique_ptr 1>]编译1>

我也尝试过使用make_pair插入数据,但也遇到了同样的问题。我错过了什么?我已经试着解决这个问题两个小时了,但我无法理解

我实际上可以通过不使用智能指针来解决这个问题:

sf::SoundBuffer* soundbuffer = new sf::SoundBuffer();
soundbuffer->loadFromFile(_file);
sf::Sound* sound = new sf::Sound(*soundbuffer);
typedef std::map<sf::SoundBuffer*, sf::Sound*> mapType;
listSound[_file].insert(mapType::value_type(soundbuffer, sound));

查看std::map:的模板定义

template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;

现在让我们看看如何实例化它:

std::map<
std::string, 
std::map<
std::unique_ptr<sf::Sound>, 
std::unique_ptr<sf::SoundBuffer>
>
> 
listSoundContainer

这里的问题是std::unique_ptr<sf::Sound>不能充当密钥。

你似乎想做的是列出某种std::pair<std::unique_ptr<sf::Sound>, std::unique_ptr<sf::SoundBuffer>>的列表

我建议使用这个替代:

std::map<
std::string, 
std::list<
std::pair<
std::unique_ptr<sf::Sound>, 
std::unique_ptr<sf::SoundBuffer>
>
>
> 
listSoundContainer

智能指针不应与STL容器结合使用。

背景是智能指针的行为并不像STL容器所期望的那样。例如,STL希望复制操作的源对象保持不变。智能指针的情况并非如此。这可能会导致你正在经历的奇怪效果。。。

编辑:我的回答不完全正确。由于C++11,可以将智能指针(例如unique_ptr)与STL容器一起使用。