2013-05-23 5 views
0

Я хочу создать multi_index_container с типом A, хранящим объекты типа C, который является производным от B, который является производным от A. Проблема в том, что в A у меня есть чистая виртуальная функция. Когда я пытаюсь скомпилировать его, я получил ошибки, которые описаны в самом низу.boost multi index container, класс с чистыми виртуальными функциями

  • Я полагаю, что это невозможно сделать-это-право?

  • Является ли вся идея испорченной?

Код

#include <iostream> 
#include <string> 
#include <boost/multi_index_container.hpp> 
#include <boost/multi_index/identity.hpp> 
#include <boost/multi_index/ordered_index.hpp> 
#include <boost/multi_index/hashed_index.hpp> 
#include <boost/multi_index/mem_fun.hpp> 



using boost::multi_index_container; 
using namespace boost::multi_index; 

class A{ 
public: 
     virtual void print()=0; 
     std::string getName() const {return name;}; 
     void setName(std::string s){name=s;}; 
     std::string name; 
}; 

template<typename T> 
class B: public A{ 
public: 
     virtual void print(){std::cout<<"B"<<name<<std::endl;} 
}; 

template<typename T> 
class C: public B<T> { 
public: 
     virtual void print(){std::cout<<"C"<<reinterpret_cast<A*>(this)->name<<std::endl;} 
}; 


typedef multi_index_container< 
     A, 
     indexed_by< 
      hashed_non_unique<const_mem_fun<A, std::string, &A::getName>> 
     > 
> Container; 


int main(){ 

     C<int> c; 
     c.setName("c"); 
     Container container; 
     container.insert(c); 
     return 0; 
} 

Ошибки

In file included from /usr/local/include/boost/aligned_storage.hpp:20:0, 
      from /usr/local/include/boost/type_traits/aligned_storage.hpp:11, 
      from /usr/local/include/boost/multi_index/detail/index_node_base.hpp:17, 
      from /usr/local/include/boost/multi_index/detail/node_type.hpp:23, 
      from /usr/local/include/boost/multi_index/detail/index_base.hpp:21, 
      from /usr/local/include/boost/multi_index/detail/base_type.hpp:21, 
      from /usr/local/include/boost/multi_index_container.hpp:33, 
      from wierdInheritance.cpp:13: 
/usr/local/include/boost/type_traits/alignment_of.hpp: In instantiation of ‘boost::detail::alignment_of_hack<A>’: 
/usr/local/include/boost/type_traits/alignment_of.hpp:71:5: instantiated from ‘const size_t boost::detail::alignment_of_impl<A>::value’ 
/usr/local/include/boost/type_traits/alignment_of.hpp:89:1: instantiated from ‘boost::alignment_of<A>’ 
/usr/local/include/boost/multi_index/detail/index_node_base.hpp:42:32: instantiated from ‘boost::multi_index::detail::pod_value_holder<A>’ 
/usr/local/include/boost/multi_index/detail/index_node_base.hpp:46:8: instantiated from ‘boost::multi_index::detail::index_node_base<A, std::allocator<A> >’ 
/usr/local/include/boost/multi_index/detail/hash_index_node.hpp:116:8: instantiated from ‘boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >’ 
/usr/local/include/boost/multi_index/hashed_index.hpp:108:54: instantiated from ‘boost::multi_index::detail::hashed_index<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName>, boost::hash<std::basic_string<char> >, std::equal_to<std::basic_string<char> >, boost::multi_index::detail::nth_layer<1, A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, std::allocator<A> >, boost::mpl::vector0<mpl_::na>, boost::multi_index::detail::hashed_non_unique_tag>’ 
/usr/local/include/boost/multi_index_container.hpp:70:7: instantiated from ‘boost::multi_index::multi_index_container<A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > > >’ 
wierdInheritance.cpp:57:19: instantiated from here 
/usr/local/include/boost/type_traits/alignment_of.hpp:42:7: error: cannot declare field ‘boost::detail::alignment_of_hack<A>::t’ to be of abstract type ‘A’ 
wierdInheritance.cpp:24:7: note: because the following virtual functions are pure within ‘A’: 
wierdInheritance.cpp:26:22: note: virtual void A::print() 
In file included from /usr/local/include/boost/multi_index_container.hpp:20:0, 
      from wierdInheritance.cpp:13: 
/usr/local/include/boost/detail/allocator_utilities.hpp: In function ‘void boost::detail::allocator::construct(void*, const Type&) [with Type = A]’: 
/usr/local/include/boost/multi_index/detail/index_base.hpp:88:5: instantiated from ‘boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type* boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::insert_(boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type*) [with Value = A, IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, Allocator = std::allocator<A>, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::node_type = boost::multi_index::detail::index_node_base<A, std::allocator<A> >, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type = const A&]’ 
/usr/local/include/boost/multi_index/hashed_index.hpp:701:63: instantiated from ‘boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::node_type* boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::insert_(boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::node_type*) [with KeyFromValue = boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName>, Hash = boost::hash<std::basic_string<char> >, Pred = std::equal_to<std::basic_string<char> >, SuperMeta = boost::multi_index::detail::nth_layer<1, A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, std::allocator<A> >, TagList = boost::mpl::vector0<mpl_::na>, Category = boost::multi_index::detail::hashed_non_unique_tag, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::node_type = boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >, typename SuperMeta::type::node_type = boost::multi_index::detail::index_node_base<A, std::allocator<A> >, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type = const A&]’ 
/usr/local/include/boost/multi_index_container.hpp:488:40: instantiated from ‘std::pair<typename boost::multi_index::detail::multi_index_base_type<Value, IndexSpecifierList, Allocator>::type::node_type*, bool> boost::multi_index::multi_index_container<Value, IndexSpecifierList, Allocator>::insert_(const Value&) [with Value = A, IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, Allocator = std::allocator<A>, typename boost::multi_index::detail::multi_index_base_type<Value, IndexSpecifierList, Allocator>::type::node_type = boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >]’ 
/usr/local/include/boost/multi_index/detail/index_base.hpp:150:30: instantiated from ‘std::pair<typename boost::multi_index::detail::multi_index_node_type<Value, IndexSpecifierList, Allocator>::type*, bool> boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::final_insert_(boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type) [with Value = A, IndexSpecifierList = boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, Allocator = std::allocator<A>, typename boost::multi_index::detail::multi_index_node_type<Value, IndexSpecifierList, Allocator>::type = boost::multi_index::detail::hashed_index_node<boost::multi_index::detail::index_node_base<A, std::allocator<A> > >, boost::multi_index::detail::index_base<Value, IndexSpecifierList, Allocator>::value_param_type = const A&]’ 
/usr/local/include/boost/multi_index/hashed_index.hpp:254:61: instantiated from ‘std::pair<boost::multi_index::detail::hashed_index_iterator<boost::multi_index::detail::hashed_index_node<typename SuperMeta::type::node_type>, boost::multi_index::detail::bucket_array<typename SuperMeta::type::final_allocator_type> >, bool> boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::insert(boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type) [with KeyFromValue = boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName>, Hash = boost::hash<std::basic_string<char> >, Pred = std::equal_to<std::basic_string<char> >, SuperMeta = boost::multi_index::detail::nth_layer<1, A, boost::multi_index::indexed_by<boost::multi_index::hashed_non_unique<boost::multi_index::const_mem_fun<A, std::basic_string<char>, &A::getName> > >, std::allocator<A> >, TagList = boost::mpl::vector0<mpl_::na>, Category = boost::multi_index::detail::hashed_non_unique_tag, typename SuperMeta::type::final_allocator_type = std::allocator<A>, typename SuperMeta::type::node_type = boost::multi_index::detail::index_node_base<A, std::allocator<A> >, boost::multi_index::detail::hashed_index<KeyFromValue, Hash, Pred, SuperMeta, TagList, Category>::value_param_type = const A&]’ 
wierdInheritance.cpp:58:27: instantiated from here 
/usr/local/include/boost/detail/allocator_utilities.hpp:178:3: error: cannot allocate an object of abstract type ‘A’ 
wierdInheritance.cpp:24:7: note: since type ‘A’ has pure virtual functions 

ответ

2

Вы не можете определить контейнер A, но вы можете определить контейнер указателей (например, shared_ptr.) В A:

typedef multi_index_container< 
     A *, 
     indexed_by< 
      hashed_non_unique<const_mem_fun<A, std::string, &A::getName>> 
     > 
> Container; 

или :

typedef multi_index_container< 
     boost::shared_ptr<A>, 
     indexed_by< 
      hashed_non_unique<const_mem_fun<A, std::string, &A::getName>> 
     > 
> Container;