Обход шаблонной специализации - PullRequest
38 голосов
/ 28 июня 2011

Предположим, что я пользователь определенной библиотеки шаблонов (CTL), которая определяет шаблон с именем, скажем, Hector

template <class T>
class Hector {...};

И в своей документации он дает много гарантий о Hector поведении шаблона. Но тогда он также определяет специализацию для определенного типа Cool

template <>
class Hector<Cool> {....};

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

В настоящее время мне действительно не нужна оптимизация, я бы предпочел сохранить все гарантии Hector. Можно ли как-нибудь обойти специализацию, не меняя код библиотеки (вы знаете, CTL очень уважаемая библиотека)? Как-нибудь вообще? Может, напишите какую-нибудь обертку? Что-нибудь? Я просто хочу, чтобы компилятор генерировал код для Hector<Cool> обычным, неоптимизированным способом со всеми гарантиями.

Ответы [ 5 ]

12 голосов
/ 28 июня 2011

Можете ли вы использовать соответствующий шаблон Reque, который не имеет нежелательной специализации?В противном случае, я думаю, вам нужно создать оболочку для Cool, чтобы специализация не использовалась.

12 голосов
/ 28 июня 2011

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

8 голосов
/ 28 июня 2011

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

Вы должны обернуть значение или использовать другой тип, например char вместо bool (они ведут себя аналогично), давая std::vector<char> вместо std::vector<bool>.

7 голосов
/ 28 июня 2011

Вот немного общего маскировки:

template <typename T>
struct Drool
{
  Drool(T d) : b(d) { }
  inline operator T() const { return b; }
  inline Drool<T> & operator=(T d) { b = d; return *this; }
private:
  T b;
};

Теперь вы можете сказать Hector<Drool<Cool>>.


Улучшенная версия в соответствии с Xeo:

template <typename T>
struct Drool
{
  Drool(const T & d) : b(d) { }
  Drool(Drool && o) = default;

  inline operator const T & () const { return b; }
  inline operator       T & ()       { return b; }

private:
  T b;
};
1 голос
/ 28 июня 2011
  1. Открыть стандарт определенную реализацию
  2. Ctrl + A
  3. Ctrl + C
  4. Создайте новый файл с именем "my_hector.h"
  5. Ctrl + V
  6. Удалите специализацию
  7. Поиск и замените #include <hector> на #include "my_hector.h"
    [Редактировать для @Xeo ;-)]
  8. Переименовать идентификаторы, которые начинаются с двух первых подчеркиваний, за которыми следует строчная букваи все идентификаторы, которые начинаются с одного начального подчеркивания, за которым следует заглавная буква.
...