0

I'm learning boost and smart pointers. During compilation I got an error, and I can't figure out what is it about. I don't understand what I am doing wrong. The problem is in constructor:

DefaultCreature(const Creature& def) : def_(def) {}

Here is my code:

#include <iostream>
#include <boost/smart_ptr.hpp>

using namespace std;
using namespace boost;

class Creature;
typedef shared_ptr<Creature> PCreature;

class Creature {
public:
    Creature(const string& name) : name_(name) {}
    const string& getName() const { return name_; }
private:
    string name_;
};

class DefaultCreature {
public:
    DefaultCreature(const Creature& def) : def_(def) {}
private:
    PCreature def_;
};

int main() {
    DefaultCreature factory(Creature("lion"));
    return 0;
}

And an error:

exercise1.cpp: In constructor ‘DefaultCreature::DefaultCreature(const Creature&)’:
exercise1.cpp:20:52: error: no matching function for call to ‘boost::shared_ptr<Creature>::shared_ptr(const Creature&)’
exercise1.cpp:20:52: note: candidates are:
In file included from /usr/local/include/boost/shared_ptr.hpp:17:0,
                 from /usr/local/include/boost/smart_ptr.hpp:21,
                 from exercise1.cpp:2:
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:472:14: note: template<class Ap> boost::shared_ptr::shared_ptr(Ap, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type)
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:472:14: note:   template argument deduction/substitution failed:
/usr/local/include/boost/smart_ptr/shared_ptr.hpp: In substitution of ‘template<class Ap> boost::shared_ptr::shared_ptr(Ap, typename boost::detail::sp_enable_if_auto_ptr<Ap, int>::type) [with Ap = Creature]’:
exercise1.cpp:20:52:   required from here
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:472:14: error: no type named ‘type’ in ‘struct boost::detail::sp_enable_if_auto_ptr<Creature, int>’
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:446:14: note: template<class Y> boost::shared_ptr::shared_ptr(std::auto_ptr<_Tp1>&)
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:446:14: note:   template argument deduction/substitution failed:
exercise1.cpp:20:52: note:   types ‘std::auto_ptr<T>’ and ‘const Creature’ have incompatible cv-qualifiers

(...)

/usr/local/include/boost/smart_ptr/shared_ptr.hpp:339:5: note: boost::shared_ptr<T>::shared_ptr() [with T = Creature]
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:339:5: note:   candidate expects 0 arguments, 1 provided
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:328:25: note: boost::shared_ptr<Creature>::shared_ptr(const boost::shared_ptr<Creature>&)
/usr/local/include/boost/smart_ptr/shared_ptr.hpp:328:25: note:   no known conversion for argument 1 from ‘const Creature’ to ‘const boost::shared_ptr<Creature>&’
Kris
  • 1,538
  • 2
  • 16
  • 27

1 Answers1

3

The argument to shared_ptr must be the address of a dynamically allocated object but the code is passing in a reference. Change to, for example:

class DefaultCreature {
public:
    DefaultCreature(const Creature& def) : def_(new Creature(def)) {}
private:
    PCreature def_;
};

or using boost::make_shared:

class DefaultCreature {
public:
    DefaultCreature(const Creature& def) :
        def_(boost::make_shared<Creature>(def)) {}
private:
    PCreature def_;
};

If the instance of DefaultCreature is the only object that has access to the object being pointed to by def_ then there is no reason for it to be a boost::shared_ptr: use boost::scoped_ptr instead. See What C++ Smart Pointer Implementations are available? for a very useful overview of smart pointers.


However, from the posted code there appears to be no reason to be using pointers of any nature. Just store a Creature instance in DefaultCreature (Creature is copyable and there is no polymorphic requirement, based on the posted code).

Community
  • 1
  • 1
hmjd
  • 120,187
  • 20
  • 207
  • 252