Имеет ли значение порядок в специализации функции в шаблоне класса - PullRequest
3 голосов
/ 21 августа 2010

Рассмотрим что-то вроде ...

template<typename T>
class Vector {
  ...
  bool operator==( const Vector<float> &rhs ) {
    // compare and return
  }

  bool operator==( const Vector<T> &rhs ) {
    // compare and return
  }
  ...
 };

Обратите внимание, что специализация выше не специализированной версии. Если бы я поместил специализированную версию ниже , а не специализированную версию, было бы сравнение Vector<float> == по-прежнему работать должным образом? Почему-то мне кажется, что я помню, что читал, что если в этом сценарии указать специализацию ниже, то, когда компилятор просматривает заголовок, он сначала увидит значение по умолчанию, увидит, что он работает, и использует его.

Ответы [ 2 ]

7 голосов
/ 21 августа 2010

Ваш пример кода не специализируется, но перегружен. Порядок имеет значение (но не в вашем коде), потому что функции должны быть объявлены до того, как станут известны в C ++. Таким образом, если одна перегрузка вызывает другую или если другая функция между вызовами вызывает набор перегрузки, вызовы могут закончиться где-то нежелательно. Ваш пример кода действителен и распространен.

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

Вы думаете о следующем правиле

Если шаблон, шаблон элемента или член шаблона класса явно специализированы, то эта специализация должна быть объявлена ​​до первого использования этой специализации, что приведет к неявной реализации в каждой единице перевода, в которой такие использование происходит; Диагностика не требуется.

Не могу не процитировать веселые высказывания Стандарта о специализациях

Размещение явных объявлений специализации для шаблонов функций, шаблонов классов, функций-членов шаблонов классов, статических данных-членов шаблонов классов, классов-членов шаблонов классов, шаблонов классов-членов шаблонов классов, шаблонов функций-членов шаблонов классов, члена функции шаблонов-членов шаблонов классов, функции-члены шаблонов-членов не шаблонных классов, шаблоны функций-членов классов-членов шаблонов классов и т. д., а также размещение объявлений частичной специализации шаблонов классов, шаблонов классов-членов не-шаблона классы, шаблоны классов членов шаблонов классов и т. д. могут влиять на то, правильно ли сформирована программа в соответствии с относительным расположением явных объявлений специализации и их точек создания в единице перевода, как указано выше и ниже. При написании специализации будьте осторожны с ее местоположением; или сделать его компиляцией будет таким испытанием, чтобы разжечь его самосожжение.

0 голосов
/ 21 августа 2010

Как написано, я считаю, что у вас есть ошибка.Вы не специализирующийся оператор ==, вы его перегружаете.Вы не можете перегружать параметр шаблона таким образом.

Если бы ваш метод был бесплатной функцией, вы могли бы специализировать его.Например,

template <typename T>
void Foo(Vector<T> x) {
   std::cout << "x" << std::endl;
}
template <>
void Foo(Vector<float> y) {
   std::cout << "y" << std::endl;
}

...
Vector<int> intVec;
Vector<float> floatVec;
Foo(intVec); //prints x
Foo(floatVec); //prints y

В этом случае, если вы вызовете Foo с помощью Vector<float>, вы вызовете специализированную версию.

Порядок имеет значение в некоторой степени.Прежде всего, компилятор всегда будет отдавать предпочтение специализации, а не специализированной форме, когда она доступна.После этого компилятор попытается создать экземпляр каждой функции по порядку.Если он сможет успешно скомпилировать, будет использована эта специализация.Если это невозможно, он перейдет к следующему.Этот принцип, называемый Сбой замещения, не является ошибкой (SFINAE).http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error имеет гораздо более подробное описание.

...