Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing polymorphic pointer containers

Can I initialize a polymorphic boost::ptr_vector with boost::assign::list_of?

#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/assign/list_of.hpp>

boost::ptr_vector<Animal> ls = boost::assign::list_of(new Ant)(new Bee)(new Cat);

This fails to compile:

error: no match for call to '(boost::assign_detail::generic_list<Ant*>) (Bear*)'

Replacing boost::ptr_vector<Animal> with std::vector<Animal*> gives the same error.


Two people suggested to manually provide the template argument Animal* to list_of:

boost::assign::list_of<Animal*>(new Ant)(new Bear)(new Cat)

But it still does not work:

boost/ptr_container/ptr_sequence_adapter.hpp: In static member function 'static boost::ptr_container_detail::sequence_config<T, VoidPtrSeq>::U* boost::ptr_container_detail::sequence_config<T, VoidPtrSeq>::get_const_pointer(Iter) [with Iter = std::_Deque_iterator<Animal*, Animal*&, Animal**>, T = Animal, VoidPtrSeq = std::vector<void*, std::allocator<void*> >, boost::ptr_container_detail::sequence_config<T, VoidPtrSeq>::U = Animal]':
boost/ptr_container/detail/reversible_ptr_container.hpp:95:71:   instantiated from 'static boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::Ty_* boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::null_clone_allocator<allow_null_values>::allocate_clone_from_iterator(Iter) [with Iter = std::_Deque_iterator<Animal*, Animal*&, Animal**>, bool allow_null_values = false, Config = boost::ptr_container_detail::sequence_config<Animal, std::vector<void*, std::allocator<void*> > >, CloneAllocator = boost::heap_clone_allocator, boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::Ty_ = Animal]'
boost/ptr_container/detail/scoped_deleter.hpp:70:21:   instantiated from 'boost::ptr_container_detail::scoped_deleter<T, CloneAllocator>::scoped_deleter(InputIterator, InputIterator) [with InputIterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>, T = Animal, CloneAllocator = boost::ptr_container_detail::reversible_ptr_container<boost::ptr_container_detail::sequence_config<Animal, std::vector<void*, std::allocator<void*> > >, boost::heap_clone_allocator>::null_clone_allocator<false>]'
boost/ptr_container/detail/reversible_ptr_container.hpp:212:44:   instantiated from 'void boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::clone_back_insert(ForwardIterator, ForwardIterator) [with ForwardIterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>, Config = boost::ptr_container_detail::sequence_config<Animal, std::vector<void*, std::allocator<void*> > >, CloneAllocator = boost::heap_clone_allocator]'
boost/ptr_container/detail/reversible_ptr_container.hpp:303:13:   instantiated from 'void boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::constructor_impl(I, I, std::forward_iterator_tag) [with I = std::_Deque_iterator<Animal*, Animal*&, Animal**>, Config = boost::ptr_container_detail::sequence_config<Animal, std::vector<void*, std::allocator<void*> > >, CloneAllocator = boost::heap_clone_allocator]'
boost/ptr_container/detail/reversible_ptr_container.hpp:378:13:   instantiated from 'boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::reversible_ptr_container(InputIterator, InputIterator, boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::allocator_type&) [with InputIterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>, Config = boost::ptr_container_detail::sequence_config<Animal, std::vector<void*, std::allocator<void*> > >, CloneAllocator = boost::heap_clone_allocator, boost::ptr_container_detail::reversible_ptr_container<Config, CloneAllocator>::allocator_type = std::allocator<void*>]'
boost/ptr_container/ptr_sequence_adapter.hpp:178:36:   instantiated from 'boost::ptr_sequence_adapter<T, VoidPtrSeq, CloneAllocator>::ptr_sequence_adapter(InputIterator, InputIterator) [with InputIterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>, T = Animal, VoidPtrSeq = std::vector<void*, std::allocator<void*> >, CloneAllocator = boost::heap_clone_allocator]'
boost/ptr_container/ptr_vector.hpp:45:9:   instantiated from 'boost::ptr_vector<T, CloneAllocator, Allocator>::ptr_vector(InputIterator, InputIterator) [with InputIterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>, T = Animal, CloneAllocator = boost::heap_clone_allocator, Allocator = std::allocator<void*>]'
boost/assign/list_of.hpp:163:46:   instantiated from 'Container boost::assign_detail::converter<DerivedTAssign, Iterator>::convert(const Container*, boost::assign_detail::default_type_tag) const [with Container = boost::ptr_vector<Animal>, DerivedTAssign = boost::assign_detail::generic_list<Animal*>, Iterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>]'
boost/assign/list_of.hpp:142:54:   instantiated from 'Container boost::assign_detail::converter<DerivedTAssign, Iterator>::convert_to_container() const [with Container = boost::ptr_vector<Animal>, DerivedTAssign = boost::assign_detail::generic_list<Animal*>, Iterator = std::_Deque_iterator<Animal*, Animal*&, Animal**>]'
boost/assign/list_of.hpp:436:81:   instantiated from 'boost::assign_detail::generic_list<T>::operator Container() const [with Container = boost::ptr_vector<Animal>, T = Animal*]'
like image 876
fredoverflow Avatar asked Jan 20 '23 19:01

fredoverflow


1 Answers

I'll take a stab at it. I think list_of is a template that is deducing the template argument. Since your argument type is the a derived class, it thinks that's the container type. The sibling classes don't match.

You might have to explicitly provide the template argument, something like this:

boost::ptr_vector<Animal> ls = boost::assign::list_of<Animal*>(new Ant)(new Bee)(new Cat);
like image 94
Fred Larson Avatar answered Jan 29 '23 02:01

Fred Larson