SFML community forums

Help => General => Topic started by: deltaphc on April 28, 2012, 08:34:36 pm

Title: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: deltaphc on April 28, 2012, 08:34:36 pm
I have a ResourceManager class that basically maintains a cache of SFML objects. At compile-time, it's giving me this error:
Code: [Select]
1>  ResourceManager.cpp
1>d:\prog\libs\sfml-2.0-rc\include\sfml\system\mutex.hpp(89): error C2248: 'sf::NonCopyable::NonCopyable' : cannot access private member declared in class 'sf::NonCopyable'
1>          d:\prog\libs\sfml-2.0-rc\include\sfml\system\noncopyable.hpp(67) : see declaration of 'sf::NonCopyable::NonCopyable'
1>          d:\prog\libs\sfml-2.0-rc\include\sfml\system\noncopyable.hpp(42) : see declaration of 'sf::NonCopyable'
1>          This diagnostic occurred in the compiler generated function 'sf::Mutex::Mutex(const sf::Mutex &)'
The thing I don't understand with this error is that I don't even use a Mutex anywhere in my code. I don't even use threading. And as far as I'm aware, all of the objects I use in ResourceManager (Texture, Music, Sound, Font) are all copyable and thus shouldn't generate this error as a side effect... that is, if I'm actually copying anything. I've tried to use object references where possible.

Some relevant source code;

ResourceManager.cpp:
http://pastebin.com/7YPtcEpH

ResourceManager.h:
http://pastebin.com/dNgBUejg

Common.h:
http://pastebin.com/YUcCQFwy

Level.h does not use any SFML types other than sf::Color.

Sorry about the amount of code. I wish I could isolate this further, but the compiler certainly isn't helping. I'm guessing that I'm missing something simple; I'm certainly no expert in all of C++'s little details.

I'm using the precompiled VS2010 package for SFML 2.0 RC. 32-bit compiler on Win7 x64.
Title: Re: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: Laurent on April 28, 2012, 08:43:54 pm
It's sf::Music which is not copyable -- indirectly because its sf::Mutex member is not. I should make sf::Music directly non-copyable.
Title: Re: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: deltaphc on April 28, 2012, 08:53:50 pm
Ah, I see. Thanks.

I suppose then my next question would be of "proper" C++ style. I'm not entirely certain where I'm copying sf::Music (and other objects for that matter). It's used in the ResourceManager::music method. If I understand things correctly, it creates an instance of sf::Music when I insert into the std::map, which I then access using an object reference which should avoid copying, so maybe the problem is when it tries to find a music entry using std::map::find(). Would it be copying sf::Music when returning an iterator?
Title: Re: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: Laurent on April 28, 2012, 10:33:39 pm
The problem is when you insert elements in the map: it stores a copy. All standard containers store copies, you can't store instances of non-copyable classes in them -- that's one of their requirements on the stored type, if you look at a detailed doc.

Note: this may not be true anymore in C++11 with move semantics, I don't know.
Title: Re: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: MorleyDev on April 29, 2012, 03:02:51 am
Note: this may not be true anymore in C++11 with move semantics, I don't know.

They provide both copy and move functions, so if it's movable you can store a non-copyable object in a standard structure such as a vector or a map.

Buuuut unless you explicitly defined those move constructors, and deltaphc is explicitly moving it onto the map (via std::move) it'll try and copy it. C++11 generally will not move without being told to.
Title: Re: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: Nexus on April 29, 2012, 09:33:39 am
C++11 generally will not move without being told to.
That's not true, move semantics are applied implicitly in many cases. Move constructor and move assignment operator are generated by the compiler, if none of The Big Five are user-defined (as far as I know, Visual Studio 2010 doesn't support that yet).

For types that are movable, there are two cases where objects can be moved implicitly: RValue expressions (e.g. arguments for a function) and function return values. In other cases (concerning LValues), std::move() is required to transfer ownership.
Title: Re: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes
Post by: MorleyDev on April 29, 2012, 08:39:31 pm
For types that are movable, there are two cases where objects can be moved implicitly: RValue expressions (e.g. arguments for a function) and function return values. In other cases (concerning LValues), std::move() is required to transfer ownership.

Hence why I said generally =) I actually had a whole paragraph explaining when it does move implicitly but got bored of writing it half-way through xD Probably should of gone into the full detail...