我可以使用boost::ptr_vector
初始化多态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);
无法编译:
error: no match for call to '(boost::assign_detail::generic_list<Ant*>) (Bear*)'
用boost::ptr_vector<Animal>
替换std::vector<Animal*>
会产生同样的错误。
有两个人建议手动提供模板参数Animal*
到list_of
:
boost::assign::list_of<Animal*>(new Ant)(new Bear)(new Cat)
但它仍然不起作用:
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*]'
答案 0 :(得分:5)
我会捅它。我认为list_of
是一个推断模板参数的模板。由于您的参数类型是派生类,因此它认为是容器类型。兄弟班级不匹配。
您可能必须显式提供模板参数,如下所示:
boost::ptr_vector<Animal> ls = boost::assign::list_of<Animal*>(new Ant)(new Bee)(new Cat);
答案 1 :(得分:3)
您不应使用list_of
分配给Boost Pointer Collections。如果其中一个构造函数抛出,那么已经构造的实例既没有被添加到容器中,也没有被list_of
删除(它需要值,而不是多态类型)。
Boost.Assignment提供了ptr_list_of()
。但是,那个只能添加同类元素(相同类型的元素)。
所以,我认为Boost.Assignment对于异构集合并不是真的有用。
答案 2 :(得分:1)
如果允许两步初始化,boost::assign::push_back
可能符合
目的:
ptr_vector<Animal> ls;
assign::push_back( ls )(new Ant)(new Bee)(new Cat);
不幸的是,我不知道做一步初始化的简洁方法。 如果我们准备一些如下所示的转换器,可能只需一步 初始化可以完成。
template< class T >
struct converter : std::vector< T > {
template< class Container >
operator Container() const {
Container c;
for ( const_iterator i = begin(), e = end(); i != e; ++ i )
c.push_back( *i );
return c;
}
};
template< class T >
converter< typename T::value_type > convert( T const& x ) {
converter< typename T::value_type > c;
c.assign( x.begin(), x.end() );
return c;
}
ptr_vector<Animal> ls =
convert( assign::list_of<Animal*>(new Ant)(new Bee)(new Cat) );
虽然这可能很长......
答案 3 :(得分:0)
这个程序编译,但我不保证它的语义:
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/assign/list_of.hpp>
struct Animal {};
struct Ant : Animal {};
struct Bee : Animal {};
struct Cat : Animal {};
boost::ptr_vector<Animal> ls=boost::assign::list_of<Animal>(Ant())(Bee())(Cat());
int main() {}
<小时/> 编辑:这也编译:
std::vector<Animal*> ls=boost::assign::list_of<Animal*>(new Ant())(new Bee())(new Cat());