Специализация шаблона функций

При чтении этого меня смущают следующие примеры:

// Example 2: Explicit specialization 
// 
template<class T> // (a) a base template 
void f( T );

template<class T> // (b) a second base template, overloads (a) 
void f( T* );     //     (function templates can't be partially 
                  //     specialized; they overload instead)

template<>        // (c) explicit specialization of (b) 
void f<>(int*);

// ...

int *p; 
f( p );           // calls (c)

Здесь (c) является явной специализацией (b).

// Example 3: The Dimov/Abrahams Example 
// 
template<class T> // (a) same old base template as before 
void f( T );

template<>        // (c) explicit specialization, this time of (a)
void f<>(int*);

template<class T> // (b) a second base template, overloads (a) 
void f( T* );

// ...

int *p; 
f( p );           // calls (b)! overload resolution ignores 
                  // specializations and operates on the base 
                  // function templates only

Здесь (c) является явной специализацией (a). Почему это? Это из-за упорядочения декларации?

Ответы

Ответ 1

Да, это из-за заказа объявления. Когда компилятор сталкивается с (c) во втором наборе, единственным специализированным шаблоном, который специализируется, является (a).

Вот почему вы должны быть осторожны при заказе своих специализированных шаблонов.

Язык программирования С++ подробно описывает это (раздел 13.5.1). Я очень рекомендую его.

Ответ 2

Это порядок, но это не только порядок. Для первого кода оба шаблона были определены ранее. Но второй был взят.

Это связано с тем, что два шаблона сравниваются и обнаруживается, что (T) соответствует любому типу, который соответствует (T*), но что (T*) не соответствует всем типам, которые соответствует (T). Таким образом, второй шаблон более специализирован. Всякий раз, когда вы помещаете явную специализацию и сопоставляете эти два шаблона, шаблоны сравниваются, а более специализированные связаны явной специализацией. Это сравнение называется "частичным упорядочением".

Ответ 3

Стандарт должен сказать следующее относительно относительного позиционирования явных объявлений специализации. [Раздел 14.7.3]

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