Я пытаюсь написать код, который использует typedef члена аргумента шаблона, но хочу указать тип по умолчанию, если аргумент шаблона не имеет этого typedef.Упрощенный пример, который я пробовал, таков:
struct DefaultType { DefaultType() { printf("Default "); } };
struct NonDefaultType { NonDefaultType() { printf("NonDefault "); } };
struct A {};
struct B { typedef NonDefaultType Type; };
template<typename T, typename Enable = void> struct Get_Type {
typedef DefaultType Type;
};
template<typename T> struct Get_Type< T, typename T::Type > {
typedef typename T::Type Type;
};
int main()
{
Get_Type<A>::Type test1;
Get_Type<B>::Type test2;
}
Я бы ожидал, что это напечатает «Default NonDefault», но вместо этого он напечатает «Default Default».Я ожидаю, что вторая строка в main () должна соответствовать специализированной версии Get_Type, потому что B :: Type существует.Однако этого не происходит.
Может кто-нибудь объяснить, что здесь происходит и как это исправить, или другой способ достижения той же цели?
Спасибо.
Изменить:
Георг дал альтернативный метод, но мне все еще интересно, почему это не работает.Согласно документам boost enable_if, способ специализировать шаблон для разных типов выглядит следующим образом:
template <class T, class Enable = void>
class A { ... };
template <class T>
class A<T, typename enable_if<is_integral<T> >::type> { ... };
template <class T>
class A<T, typename enable_if<is_float<T> >::type> { ... };
Это работает, потому что enable_if имеет тип как typedef, а enable_if нет.
Я не понимаю, чем это отличается от моей версии, где вместо использования enable_if я просто использую T :: Type напрямую.Если T :: Type существует, разве это не будет то же самое, что enable_if :: type в вышеприведенном примере, и вызовет ли специализацию выбор?И если T :: Type не существует, разве это не будет то же самое, что enable_if :: type, не существующий и вызывающий выбор версии по умолчанию в приведенном выше примере?