I need to have a std::vector
of boost::ptr_vector
s. To make their management easier, I enclosed the boost::ptr_vector in a class (Zoo
) and made a std::vector of it (allZoos
). Look at a minimal code for reproducing this:
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/utility.hpp>
class Animal
{
public:
virtual char type() = 0;
};
class Cat : public Animal
{
public:
char type() { return 1; }
};
class Zoo
{
public:
boost::ptr_vector<Animal> animals;
};
int main()
{
std::vector<Zoo> allZoos;
Zoo ourCityZoo;
ourCityZoo.animals.push_back(new Cat());
//Uncommenting any of the lines below causes error:
//allZoos.push_back(ourCityZoo);
//allZoos.clear();
return 0;
}
Declaring allZoos
is okay, but calling any of its member functions causes the compiler error: (The full error log was so long, not posted)
C2259: 'Animal' : cannot instantiate abstract class c:\boost_1_49_0\boost\ptr_container\clone_allocator.hpp 34 1
This had nothing to do with boost's noncopyable utility class and custom new_clone
functions and I tried them with no luck. How can that be solved?
(I'm using VS2010)
Actually, reading into where the error appears would've helped. It's stated clear and plainly in the Boost source:
template< class T >
inline T* new_clone( const T& r )
{
//
// @remark: if you get a compile-error here,
// it is most likely because you did not
// define new_clone( const T& ) in the namespace
// of T.
//
T* res = new T( r );
BOOST_ASSERT( typeid(r) == typeid(*res) &&
"Default new_clone() sliced object!" );
return res;
}
If you don't specify a way to clone the type, it will try to do so by simply copying it, which isn't possible with abstract classes. Add an appropriate clone
method to the abstract_class
and a new_clone
function in its namespace and you'll be fine.
Here's a fixed version of your code.