у меня есть multi_index_container
из struct Person
:
struct Person {
std::string firstName;
std::string lastName;
int id;
bool operator <(const Person& rhs) const {return id < rhs.id;}
};
//index tags
struct BaseIndexTag {};
struct FirstName : BaseIndexTag {};
struct LastName : BaseIndexTag {};
struct ID : BaseIndexTag {};
namespace bmi = boost::multi_index;
typedef boost::multi_index_container<
Person,
bmi::indexed_by<
//PinsConnection operator < ordering
bmi::ordered_unique<bmi::tag<ID>, bmi::identity<Person> >,
//order by first name
bmi::ordered_non_unique<bmi::tag<FirstName>, bmi::member<Person, std::string, &Person::firstName> >,
//Order by last name
bmi::ordered_non_unique<bmi::tag<LastName>, bmi::member<Person, std::string, &Person::lastName> >
>
> PersonMultiSet;
и класс-обёртка для наддува iterator_adaptor
:
template <
typename I //Internal iterator type
, typename C //Container class
>
class IteratorAdaptor : public boost::iterator_adaptor <
IteratorAdaptor<I,C>, //Derived
I, //Base
boost::use_default, //Value
boost::forward_traversal_tag> //Traversal
{
private:
friend class boost::iterator_core_access;
friend C;
public:
IteratorAdaptor()
: typename IteratorAdaptor<I,C>::iterator_adaptor_() {}
explicit IteratorAdaptor(I& b)
: typename IteratorAdaptor<I,C>::iterator_adaptor_(b) {}
};
Наконец, я написал класс-оболочку для PersonMultiSet
для того, чтобы предоставить чистый интерфейс пользователям этого класса и избежать повышения multi_index_container
несколько громоздкий интерфейс:
class PersonContainer {
public:
typedef IteratorAdaptor<PersonMultiSet::index<ID>::type::iterator, PersonContainer> IDIterator;
typedef IteratorAdaptor<PersonMultiSet::index<ID>::type::const_iterator, PersonContainer> IDConstIterator;
typedef IteratorAdaptor<PersonMultiSet::index<FirstName>::type::iterator, PersonContainer> FirstNameIterator;
typedef IteratorAdaptor<PersonMultiSet::index<FirstName>::type::const_iterator, PersonContainer> FirstNameConstIterator;
typedef IteratorAdaptor<PersonMultiSet::index<LastName>::type::iterator, PersonContainer> LastNameIterator;
typedef IteratorAdaptor<PersonMultiSet::index<LastName>::type::const_iterator, PersonContainer> LastNameConstIterator;
template <typename T> //tag
void foo(IteratorAdaptor<PersonMultiSet::index<T>::type::iterator, PersonContainer> &it)
{
//...
}
private:
PersonMultiSet people;
};
Компиляция этого кода под VS2010 приводит к следующей ошибке при объявлении функции foo:
1> main.cpp
1>main.cpp(70): warning C4346: 'boost::multi_index::multi_index_container<Value,IndexSpecifierList>::index<T>::boost::multi_index::multi_index_container<Value1,IndexSpecifierList1,Allocator1>::index<Tag>::type::iterator' : dependent name is not a type
1> with
1> [
1> Value=Person,
1> IndexSpecifierList=boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::tag<ID>,boost::multi_index::identity<Person>>,boost::multi_index::ordered_non_unique<boost::multi_index::tag<FirstName>,boost::multi_index::member<Person,std::string,pointer-to-member(0x0)>>,boost::multi_index::ordered_non_unique<boost::multi_index::tag<LastName>,boost::multi_index::member<Person,std::string,pointer-to-member(0x20)>>>
1> ]
1> prefix with 'typename' to indicate a type
1>main.cpp(70): error C2923: 'IteratorAdaptor' : 'boost::multi_index::multi_index_container<Value,IndexSpecifierList>::index<T>::boost::multi_index::multi_index_container<Value1,IndexSpecifierList1,Allocator1>::index<Tag>::type::iterator' is not a valid template type argument for parameter 'I'
1> with
1> [
1> Value=Person,
1> IndexSpecifierList=boost::multi_index::indexed_by<boost::multi_index::ordered_unique<boost::multi_index::tag<ID>,boost::multi_index::identity<Person>>,boost::multi_index::ordered_non_unique<boost::multi_index::tag<FirstName>,boost::multi_index::member<Person,std::string,pointer-to-member(0x0)>>,boost::multi_index::ordered_non_unique<boost::multi_index::tag<LastName>,boost::multi_index::member<Person,std::string,pointer-to-member(0x20)>>>
1> ]
1>
1>Build FAILED.
Кажется, что компилятор не позволяет тип IteratorAdaptor<PersonMultiSet::index<T>::type::iterator
быть определенным при первом использовании (я получаю эту ошибку еще до того, как пытаюсь создать экземпляр PersonContainer
или позвоните фу).
Что я делаю неправильно?
Компилятор дает подсказку, что не так:
префикс с ‘typename’, чтобы указать тип
Итак, вам нужно добавить typename
перед «проблемным» параметром.
void foo(IteratorAdaptor<PersonMultiSet::index<T>::type::iterator,
PersonContainer> &it)
должно быть:
// vvvvvvvv
void foo( IteratorAdaptor< typename PersonMultiSet::index<T>::type::iterator,
PersonContainer> &it)
Других решений пока нет …