2011-12-25 2 views
1

У меня есть вопрос, связанный с дизайном реализации класса шаблона.Шаблон внутренних классов на основе параметров

шаблон AT может быть специализированы только параметры шаблона A1 и A2:

AT<A1> a; 

or 

AT<A2> a; 

Шаблон имеет функцию, которая может использовать B1 и B2 классы. В частности, когда шаблон специализирован с классом A1, функция должна использовать B1 и для A2, B2 следует использовать. Например:

template< class T > class AT : public A 
{ 
    int size; 

    public: 
    int f() 
    { 
     if (dynamic_cast<A1*> this != 0) { 
      size = sizeof(B1); 
     } 
     else { 
      size = sizeof(B2); 
     } 
    } 

    ... 
}; 

Как В1 и В2 классы, связанные с внутренней A1 и реализации А2, то предпочтительно, чтобы не сделать конечный пользователь в курсе об их существовании, так специализации шаблона, как

AT<A1, B1> a; 

неприемлемо.

Каков наилучший способ создания такого класса шаблонов и разрешить внутреннее дифференцирование на основе класса, с которым был специализирован шаблон?

Спасибо!

+0

Я изменил тег 'rtti' на' template'. Этот вопрос больше связан с шаблонами * compile time *, чем с * информацией типа RunTime *. –

+0

Мне сложно понять ваш вопрос. Что означает 'a AT ;' должно означать? (Недействительный синтаксис afaict.) 'AT ' невозможен вообще, AT имеет только один аргумент шаблона. 'dynamic_cast' - это среда выполнения, я не думаю, что вы хотите, чтобы там - это часть вашей проблемы? – Mat

+0

Перечитывая вопрос, я начинаю сомневаться в том, что то, что я понял и что вам нужно, одно и то же. Вы намерены использовать 'AT ' полиморфно через указатели/ссылки на 'A'? Если это так, тогда вам нужен RTTI, но это, скорее всего, должно быть разрешено с помощью функции 'f'' virtual' и с отправкой реализации в соответствующее переопределение. –

ответ

4

Вы можете создать простой тип признака для карты типов его:

template <typename T> 
struct B_type;   // Generic type mapping declaration (undefined) 
template <> 
struct B_type<A1> {  // Mapping of A1 -> B1 
    typedef B1 type; 
}; 
template <> 
struct B_type<A2> {  // Mappint of A2 -> B2 
    typedef B2 type; 
}; 

И затем использовать его внутри:

template <typename T> 
int AT<T>::f() { 
    return sizeof(typename B_type<T>::type); 
} 
0

В более простом случае можно использовать черты типа.

Если вам нужно что-то более сложное, вы можете использовать частное/защищенное наследование или просто создать специализированный объект (спасибо Дэвиду, указав, что невозможно использовать класс-член), который имеет явную специализацию для A1 и A2 и который выбирает правильную функцию.

template<> class sizeofFunc<A1> 
{ 
    public: 
     static int getSize(T obj) { 
      return sizeof(B1); 
     } 
}; 

template<> class sizeofFunc<A2> 
{ 
    public: 
     static int getSize(T obj) { 
      return sizeof(B2); 
     } 
}; 

template< class T > class AT : public A, private sizeofFunc<T> 
{ 
    int size; 

    public: 
    int f() 
    { 
     size = getSize(something); 
    } 

    ... 
}; 
+0

Вам понадобится реорганизовать код. Язык не позволяет вам специализировать член шаблона внутри определения класса (т. Е. 'SizeofFunc ' должен быть перемещен за пределы 'AT'). Кроме того, вам не нужно указывать определение неспециализированного шаблона 'sizeofFunc'. –

+0

Дэвид: Я этого не знал. – stativ

+0

На самом деле я использую личное наследование в этом случае.Это должно быть причиной, по которой я научился использовать наследование в таких случаях. Надеюсь, на этот раз я запомню это лучше. Спасибо, что указали. – stativ

Смежные вопросы