C ++ CRTP и доступ к производным вложенным определениям типов из base

edit: Я помещу здесь ссылку на github, когда закончу изменять свой дизайн для всех, кто заинтересована.

Справочная информация

Я заменяю boost :: intrusive , intrusive_set своей собственной реализацией в виде 64-битных скомпилированных материалов с интрузивным набором 3 x 8-байтовых указателей в мои контейнерные узлы. мой контейнер имеет ограничение в 2 ^ 16 узлов, поэтому я могу уменьшить его до 4 байтов на узел с 2x 16-битными порядковыми номерами смещения (что является 6-кратным уменьшением размера).

В приведенном ниже примере база - это контейнер с интрузивной установкой. производный класс имеет std :: vector > . очевидно, что с этим уровнем косвенности мне нужно иметь кучу вложенных typedef в производных, на которые я хотел бы сослаться в base.

п.с., контейнеры предназначены для AST языка описания данных. Таким образом, содержащиеся элементы являются небольшими типами данных, и 3 x 8 байтов очень важны. Тем более, что контейнеры используются для проверки наборов данных в тесных циклах.

Проблема изолирована

Я хочу достичь следующей семантики:

template<typename TWO>
class base
{
public:
  void foo(typename TWO::dummy & d);
};

template<typename DUMMY>
class derived
  : private base< derived<DUMMY> >
{
public:
  typedef DUMMY dummy;
};

struct tag{};

int main()
{
  derived<tag> foo;
}

Но я не могу получить доступ к вложенному определению типов из базы. Вот что clang должен сказать по этому поводу:

main.cc: In instantiation of ‘base<derived<tag> >’:
main.cc:9:7:   instantiated from ‘derived<tag>’
main.cc:20:16:   instantiated from here
main.cc:5:8: error: no type named ‘dummy’ in ‘class derived<tag>’

Вместо этого я должен сделать:

template<typename type_key>
class traits
{
public:
  typedef type_key dummy;
};

template<typename TWO, typename type_key>
class base
{ 
public:
  void foo(typename traits<type_key>::dummy & d);
};

template<typename DUMMY>
class derived
  : private base< derived<DUMMY>, DUMMY >
{
public:
  typedef DUMMY dummy;
};

struct tag{};

int main()
{
  derived<tag> foo;
}

Это единственный способ достичь моего варианта использования? это просто делает вещи намного более многословными.Я полагаю, что производные могут также быть производными от черт, чтобы сэкономить некоторые нажатия клавиш.

Другой вариант - не использовать вывод и напрямую связать логику с тем, что выводится в настоящее время. Тем не менее, хотелось бы индивидуально создать базу юнит-тестов.

16
задан Hassan Syed 13 November 2011 в 19:24
поделиться