user1873947
user1873947

Reputation: 1811

boost::shared_ptr and nullptr in default template function argument

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!

Upvotes: 1

Views: 6228

Answers (3)

Vicente Botet Escriba
Vicente Botet Escriba

Reputation: 4345

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

Upvotes: 3

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506847

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.

Upvotes: 2

Guillaume Paris
Guillaume Paris

Reputation: 10539

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

Upvotes: 2

Related Questions