Reputation:
I am using Visual Studio 2012. I have a map that looks like this:
std::map<std::string,std::map<std::unique_ptr<sf::Sound>,std::unique_ptr<sf::SoundBuffer>>> listSoundContainer;
I'm trying to insert data like this:
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)));
}
and im getting the following error at compile time:
microsoft visual studio 11.0\vc\include\utility(182): error C2248: 'std::unique_ptr<_Ty>::unique_ptr' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 1> with 1>
[ 1> _Ty=sf::Sound 1> ] 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\memory(1447) : see declaration of 'std::unique_ptr<_Ty>::unique_ptr' 1> with 1> [ 1> _Ty=sf::Sound 1> ] 1> c:\program files (x86)\microsoft visual studio 11.0\vc\include\xmemory0(617) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2>::pair(std::pair<_Ty1,_Ty2> &&,void **)' being compiled 1> with 1> [ 1>
_Ty1=const std::unique_ptr, 1> _Ty2=std::unique_ptr, 1> _Kty=std::unique_ptr, 1> _Ty=std::unique_ptr 1> ]
I have also tried to insert data using make_pair with the same problem. What am I missing? Ive been trying to solve this problem for 2 hours now and can't get my head around it.
I can actually solve this problem by NOT using smart pointers:
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));
Upvotes: 9
Views: 4164
Reputation: 1424
In C++20 it's now possible to use unique_ptr
keys within a map, using Heterogenous Lookup.
In fact, being able to use unique_ptr
keys was one of the motivations for introducing heterogenous lookup.
Working example: https://godbolt.org/z/PTjEjb7Go
Upvotes: 0
Reputation: 36
Smart pointers should not be used in combination with STL containers.
The background is that smart pointers do not behave as expected by the STL-containers. For instance, the STL expects source objects of a copy operation to remain unchanged. This is not the case with smart pointers. This can lead to strange effects as you are experiencing...
EDIT: My answer was not fully correct. Since C++11 it is possible to use smart pointers, e.g. unique_ptr, with STL-containers.
Upvotes: -2
Reputation: 1747
Look at the template definition for std::map
:
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
And now lets look at how you try to instantiate it:
std::map<
std::string,
std::map<
std::unique_ptr<sf::Sound>,
std::unique_ptr<sf::SoundBuffer>
>
>
listSoundContainer
The problem here is that a std::unique_ptr<sf::Sound>
cannot act as a key.
What you seem trying to do is to make some kind of list of std::pair<std::unique_ptr<sf::Sound>,
std::unique_ptr<sf::SoundBuffer>>
I would suggest using this instead:
std::map<
std::string,
std::list<
std::pair<
std::unique_ptr<sf::Sound>,
std::unique_ptr<sf::SoundBuffer>
>
>
>
listSoundContainer
Upvotes: 3