boost::shared_ptr and nullptr in default template function argument

纵然是瞬间 提交于 2019-12-24 11:37:35

问题


So, here is my class and its function:

template <class T>
class cResourceManager
{
public:
    bool add(const std::string & key, boost::shared_ptr<T> ptr = nullptr); 
private:
    std::map <const std::string, boost::shared_ptr<T> > resources;
};

template <class T>
bool cResourceManager<T>::add(const std::string & key, boost::shared_ptr<T> ptr)
{
    if (resources.find(key) == resources.end())
    {
        if(ptr != nullptr) //we have the object
        {
            resources.insert(std::pair<const std::string, boost::shared_ptr<T>>(key, ptr));
        return true;
    }
    else //we need to load object using sfml loadFromFile
    {
        T tempResource;
        tempResource.loadFromFile(key);
        resources.insert(std::pair<const std::string, boost::shared_ptr<T>>(key, new T(tempResource)));
        if(resources[key] == nullptr) return false;
        else return true;
    }
}
}     

That class is in static library, it compliles without problem. However, when I use it in normal application:

cResourceManager<sf::Texture> resourceManager;
resourceManager.add("1.PNG");

I get error: error: default argument for parameter of type ‘boost::shared_ptr’ has type ‘std::nullptr_t’

I have no idea what's wrong here, can't shared_ptr have nullptr value? I use g++ 4.7 with -std=c++11

thanks!


回答1:


Boost::shared_ptr will support constructor from std::nullptr_t since version 1.53.




回答2:


this will works with std::shared_ptr instead of boost::shared_ptr I think




回答3:


According to http://www.boost.org/doc/libs/1_52_0/libs/smart_ptr/shared_ptr.htm#Members , boost::shared_ptr cannot be initialized by a null pointer constant because for the pointer-taking constructor, it is templated by Y* where Y is a template parameter. A conversion of a null pointer constant to Y* is not considered when deducing Y*, so that constructor will have a deduction failure and is ignored when passing nullptr.

But std::shared_ptr can accept it because it has a std::nullptr_t overload, so if you want, you can switch.

Note that passing nullptr is different from passing a null pointer like (T*)nullptr. The latter won't use a constexpr constructor but the former will (among other differences). So in the former case if your pointer is a namespace scope variable, it has constant initialization and will not induce initialization races with namespace scope objects in other translation units.



来源:https://stackoverflow.com/questions/13787103/boostshared-ptr-and-nullptr-in-default-template-function-argument

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!