Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: C2248 NonCopyable error in Mutex.hpp, even though I'm not using mutexes  (Read 3594 times)

0 Members and 1 Guest are viewing this topic.

deltaphc

  • Newbie
  • *
  • Posts: 4
    • View Profile
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.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
It's sf::Music which is not copyable -- indirectly because its sf::Mutex member is not. I should make sf::Music directly non-copyable.
Laurent Gomila - SFML developer

deltaphc

  • Newbie
  • *
  • Posts: 4
    • View Profile
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?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
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.
Laurent Gomila - SFML developer

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
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.
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
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.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
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...
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.