初始化多态指针容器

发布于 2024-11-06 12:11:25 字数 5846 浏览 1 评论 0原文

我可以使用 boost::assign::list_of 初始化多态 boost::ptr_vector 吗?

#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*)'

std::vector 替换 boost::ptr_vector 会产生相同的错误。


有两个人建议手动向 list_of 提供模板参数 Animal*

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*]'

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*]'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半边脸i 2024-11-13 12:11:26

我会尝试一下。我认为 list_of 是一个推导模板参数的模板。由于您的参数类型是派生类,因此它认为这是容器类型。兄弟班级不匹配。

您可能必须显式提供模板参数,如下所示:

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

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);
怪我太投入 2024-11-13 12:11:26

您不应使用 list_of 来分配给 Boost 指针集合。如果其中一个构造函数抛出异常,则已构造的实例既不会被添加到容器中,也不会被 list_of (它需要值,而不是多态类型)删除。

Boost.Assignment 提供 ptr_list_of()< /code>相反。然而,它只能添加同类元素(相同类型的元素)。

所以,我认为 Boost.Assignment 对于异构集合来说并不是很有用。

You shouldn't use list_of to assign to Boost Pointer Collections. If one of the constructors throws, the already-constructed instances have neither been added to the container yet, nor will they be deleted by list_of (which expects values, not polymorphic types).

Boost.Assignment provides ptr_list_of() instead. That one, however, can only add homogeneous elements (elements of the same type).

So, I think that Boost.Assignment isn't really useful for heterogeneous collections.

冷血 2024-11-13 12:11:26

如果允许两步初始化,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) );

虽然这可能会很长...

If two step initialization is allowed, boost::assign::push_back might meet the
purpose:

ptr_vector<Animal> ls;
assign::push_back( ls )(new Ant)(new Bee)(new Cat);

Unfortunately, I don't know a concise way to do one step initialization.
If we prepare some converter like the following, probably one step
initialization can be done.

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) );

This might be lengthy though...

黎夕旧梦 2024-11-13 12:11:26

该程序可以编译,但我不保证其语义:

#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() {}


EDIT: This also compiles:

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

This program compiles, but I don't guarantee its semantics:

#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() {}


EDIT: This also compiles:

std::vector<Animal*> ls=boost::assign::list_of<Animal*>(new Ant())(new Bee())(new Cat());
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文