edit: Я добавлю сюда ссылку на github, когда закончу изменять свой дизайн для всех, кому это интересно.
Фон
Я заменяю boost::intrusive
, intrusive_set
своей собственной реализацией в виде 64-разрядных скомпилированных наборов вторжений 3 x 8-байтовых указателей на мои узлы контейнера.мой контейнер имеет ограничение в 2 ^ 16 узлов, поэтому я могу уменьшить его до 4 байтов на узел с помощью 2-х 16-битных смещенных ординалов (что в 6 раз меньше размера).
В приведенном ниже примере base
является контейнером с навязчивым набором.Класс derived
имеет std::vector<container_entry_type<entry_type> >
.очевидно, что при таком уровне косвенности мне нужно иметь набор вложенных typedef в производных, на которые я хотел бы сослаться в base.
ps, контейнеры предназначены для 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;
}
Но я не могу получить доступ к вложенной typedef с базы.Вот что должен сказать по этому поводу Кланг:
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;
}
Это единственный способ достичь моего варианта использования?это только делает вещи намного более многословными.Я предполагаю, что производная может также быть производной от черт, чтобы сохранить некоторые нажатия клавиш.
Другой выбор - не использовать деривацию и связывать логику прямо с тем, что в настоящее время получено.Однако я бы хотел индивидуально пройти тестовую базу.