2015-04-16 2 views
1

Я специализируюсь шаблон на перечислениеИспользование специализированного шаблона и имя опции перечислимую

template<> 
class specialized_class<user_option=CHOICE_ENUM::CHOSEN_OPTION> 
{ 

public: 

    typedef second_class<user_option> obj_type; 

Здесь, чтобы определить second_class, мне нужно знать, какой пользователь выбрал тип. Мне нужно указать выбранный вариант. Однако вторая строка моего кода является незаконным синтаксисом. Как делать то, что мне нужно?

Даже если

typedef second_class<CHOICE_ENUM::CHOSEN_OPTION> obj_type; 

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

+1

вы можете указать CHOICE_ENUM :: CHOSEN_OPTION во второй строке, так как вы знаете, что вы специализируетесь на CHOICE_ENUM :: CHOSEN_OPTION – ProgramCpp

+0

Спасибо, но это был бы волшебный тип. Я предпочитаю избегать этого. – ar2015

+0

@ ar2015 Это не _magic_. Было бы волшебным, если бы не было понятно, почему это значение, которое должно/должно использоваться, но в этом случае это единственное возможное значение, потому что это тип шаблона, который вы явно использовали для выполнения специализации. –

ответ

2

Если вы пытаетесь уменьшить количество ошибок CHOICE_ENUM::CHOSEN_OPTION по специализации. Возможно, достаточно.

enum Enum 
{ 
    E1, 
    E2 
}; 

template<Enum E> 
class Foo 
{ 
}; 

template<Enum E> 
class Bar 
{ 
}; 

template<> 
class Foo<E2> // 1 occurrence to change if copy/pasted for a new specialization 
{ 
public: 
    static const Enum enum_value = E2; // Last occurrence to change 

    typedef Bar<enum_value> obj_type; 
}; 
+0

Кажется, нет другого простого способа – ar2015

+0

@ ar2015 Я не знаю другого пути. Если вы узнаете, в противном случае, дайте мне знать. :) –

0

Вы можете использовать частичную специализацию вместе с некоторыми sfinae, но решение заканчивается небольшим количеством wtf-фактора. Here's демо.

Во-первых, изменить основной шаблон

template<CHOICE_ENUM e, typename Enable = void> 
class specialized_class; 

параметр по умолчанию позволяет продолжать использовать specialized_class так, как вы использовали его раньше, - вы все равно можете претендовать его шаблон класса в один параметр. Теперь конвертировать ваши полные специализации в частичную специализацию + SFINAE:

template <CHOICE_ENUM user_option> 
class specialized_class<user_option, 
     std::enable_if_t<user_option == CHOICE_ENUM::CHOSEN_OPTION>> 
{ 
    //stuff 
}; 
1

Это немного трудно сказать, из краткого примера, но вы можете фактор общих части специализации в базовый класс, чтобы избежать некоторого повторения параметров ,

template<CHOICE_ENUM option> 
struct user_option_base { 
    static const CHOICE_ENUM user_option = option; 
}; 

template<> 
class specialized_class<CHOICE_ENUM::CHOSEN_OPTION> 
    : user_option_base<CHOICE_ENUM::CHOSEN_OPTION> 
{ 
public: 
    typedef second_class<specialized_class::user_option> obj_type; 

Чтобы избежать квалификации specialized_class::user_option, вы можете использовать using user_option_base::user_option;.

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