Частичная специализация шаблона - любой реальный пример? - PullRequest
4 голосов
/ 27 августа 2009

Я размышляю о partial specialization. Хотя я понимаю идею, я не видел реального применения этой техники. Full specialization используется во многих местах в STL, поэтому у меня нет проблем с этим. Не могли бы вы рассказать мне о реальном примере использования partial specialization? Если пример в STL, это было бы лучше!

Ответы [ 3 ]

13 голосов
/ 27 августа 2009

C ++ 0x поставляется с unique_ptr, который является заменой для auto_ptr, который будет устаревшим.

Если вы используете unique_ptr с типом массива, он использует delete[] для его освобождения, а также для предоставления operator[] и т. Д. Если вы используете его без типа массива, он использует delete. Это требует частичной специализации шаблона, например

template<typename T>
struct my_unique_ptr { ... };

template<typename T>
struct my_unique_ptr<T[]> { ... };

Другое использование (хотя и очень сомнительное) - std::vector<bool, Allocator> в стандартной библиотеке. Специализация bool использует оптимизацию пространства для упаковки bool в отдельные биты

template<typename T, typename Allocator = std::allocator<T> >
struct vector { ... };

template<typename Allocator>
struct vector<bool, Allocator> { ... };

Еще одно использование - с std::iterator_traits<T>. Итераторы должны определять вложенные typedefs value_type, reference и другие для правильных типов (для const итератора, например, reference обычно будет T const&), чтобы алгоритмы могли использовать их для своей работы. Основной шаблон использует членов-членов типа итератора по очереди

template<typename T>
struct iterator_traits { 
  typedef typename T::value_type value_type; 
  ...
};

Для указателей это, конечно, не работает. Для них есть частичная специализация

template<typename T>
struct iterator_traits<T*> {
  typedef T value_type;
  ...
};
5 голосов
/ 28 августа 2009

В некоторых реализациях stl коллекции, такие как std::vector и std::list, используют частичную специализацию шаблонов, чтобы уменьшить количество кода, генерируемого для коллекций указателей.

Каждый экземпляр шаблона для типа T создает новый код. Однако типы указателей фактически одинаковы, поэтому генерация нового кода для каждого типа является пустой тратой. Это можно уменьшить, реализовав закрытую часть коллекций указателей с указателями void, а затем приведя их к соответствующему типу в открытом интерфейсе. Это значительно уменьшает код, сгенерированный для коллекций указателей.

Я думаю, что это описано в Effective STL.

1 голос
/ 27 августа 2009

Взято из MSDN (частичная специализация шаблонов классов (C ++))

// partial_specialization_of_class_templates.cpp
template <class T> struct PTS {
   enum {
      IsPointer = 0,
      IsPointerToDataMember = 0
   };
};

template <class T> struct PTS<T*> {
   enum {
      IsPointer = 1,
      IsPointerToDataMember = 0
   };
};

template <class T, class U> struct PTS<T U::*> {
   enum {
      IsPointer = 0,
      IsPointerToDataMember = 1
   };
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...