Явные специализации шаблонов функций не должны использоваться
Явные специализации шаблонов функций не должны использоваться.
Явная специализация шаблонов функций может вызвать непредвиденные проблемы с разрешением перегрузки в C++. Разрешение перегрузки:
Сначала выполняется поиск нешаблонной простой старой функции, имеющей соответствующий список параметров.
Если такая функция недоступна, разрешение перегрузки выбирает ближайший шаблон совпадающей функции.
После выбора шаблона функции компилятор выполняет поиск подходящей специализации шаблона.
Специализация шаблона не изменяет порядок процесса разрешения перегрузки, что может привести к путанице и неожиданному поведению. Рассмотрим фрагмент кода:
//(a) base template
template<class T> void f( T );
//(b) specialization of (a)
template<> void f<>(int*);
//...
//(c) overloads (a)
template<class T> void f( T* );
//...
main(){
int *p;
f( p );
}f() вызывается с помощью int* в main(), вы можете ожидать специализацию для int*, с пометкой (b), подлежит вызову. Компилятор разрешает вызов f() следующим образом:
Компилятор выполняет поиск простой старой функции с типом ввода int*.
Поскольку такой функции нет, компилятор выполняет поиск шаблона функции, имеющего ближайший совпадающий список параметров.
Шаблон (c), который принимает общий указатель в качестве ввода, является ближайшим совпадением для f(int*).
Шаблон (c) не является специализированным. Процесс разрешения перегрузки останавливается и вызывает шаблон в (c).
Несмотря на наличие специализированного шаблона для int* ввод типа определен в (b), перегрузка разрешается шаблону в (c), что может быть неожиданным.
При специализации шаблона перегруженной функции процесс разрешения перегрузки может стать более запутанным. Какой из перегруженных шаблонов становится специализированным, зависит от порядка объявления. Рассмотрим фрагмент кода:
//(a)
template <typename T> void F1(T t){}
//(b)
template <typename T> void F1(T* p){}
//(x): Specialization of template
template <> void F1<>(uint16_t* p){}//(a)
template <typename T> void F1(T t){}
//(x): Specialization of template
template <> void F1<>(uint16_t* p){}
//(b)
template <typename T> void F1(T* p){}Чтобы избежать путаницы в коде и неожиданного поведения, избегайте специализированных шаблонов функций. Если необходимо специализировать шаблон функции, напишите один шаблон функции, который делегирует шаблону класса. Например, в этом коде шаблон функции f() делегаты в класс f_implementation.
template<class T> class f_implementation;
template<class T> void f( T t ) {
FImpl<T>::f( t ); //Don't specialize function template
}
template<class T> class f_implementation {
static void f( T t ); // Specializing class templates is permissible.
}При явной специализации шаблона функции Polyspace ® помечает шаблон функции.
Если вы ожидаете нарушения правила, но не видите его, обратитесь к разделу Нарушения стандартов кодирования не отображаются.
| Группа: Шаблоны |
| Категория: Обязательно, Автоматизировано |