简体   繁体   中英

unique_ptr(std::nullptr_t) and templates

I'm making a component-entity system for a game.

I have a class, Object, which is just a shell to hold components, which in turn are stored in the object in a std::map as a (typeid, unique_ptr<>) pair. Each component is a class derived from Component.

The Object class has several template functions (the class itself is not a template though) to facilitate access and modification to the components. The template definitions are in the header file with the class definition (to avoid linker errors).

When compiling, I receive the following error (in VS2012):

error C2664: 'std::unique_ptr<_Ty,_Dx>::unique_ptr(std::nullptr_t) throw()' : cannot convert parameter 1 from 'std::unique_ptr<_Ty>' to 'std::nullptr_t'
      with
      [
          _Ty=Positional,
          _Dx=std::default_delete<Positional>
      ]
      and
      [
          _Ty=Component
      ]
      nullptr can only be converted to pointer or handle types
see reference to function template instantiation 'std::unique_ptr<_Ty,_Dx> Object::__GetComponent<Positional>(void)' being compiled
          with
          [
              _Ty=Positional,
              _Dx=std::default_delete<Positional>
          ]

in reference to the following function:

template <typename T> std::unique_ptr<T>
Object::__GetComponent()
{
    if(m_components.count(&typeid(T)) != 0)
    {
        return m_components[&typeid(T)];
    }
    else 
    {
        return std::unique_ptr<T>(new T);
    }
}

What is going on here? No where in my code do I use a custom deleter, nor do I try to store a nullptr in a unique_ptr instance. I guess more specifically, what is trying to cause the conversion from unique_ptr<> to nullptr_t?

I also receive this error for every component, not just the 'Positional' one listed.

Here:

return m_components[&typeid(T)];

you're trying to return a copy of one of the unique pointers in the map. Unique pointers can't be copied; only one can own any given object, hence the "unique" part of the name.

The error message is rather cryptic; a more sensible compiler would complain that the copy constructor is deleted, which should make it clear what's wrong. This is apparently ignoring the copy constructor altogether, and only mentioning a different, unsuitable constructor.

It's not entirely clear what you actually want to return, and how the ownership of the objects should be managed. You'll need to decide on the strategy for managing the objects, and use smart pointers appropriately. Perhaps you want to remove the element from the map and return its unique pointer (by moving it). Perhaps you want to make a new copy of the object and return a unique pointer managing that. Perhaps you want to return a non-owning pointer; but then it's not clear what to do if it's not in the map (add a new element, maybe?). Perhaps you want to store and return shared pointers, so that they can remain in the map but share ownership with whoever calls this function. Perhaps you want to do something entirely different.

Also, you shouldn't call the function __GetComponent . That's a reserved name .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM