Формулировка C ++ для явной специализации шаблона - PullRequest
0 голосов
/ 11 сентября 2018

Если мы рассмотрим перегрузку шаблонов функций, стандартное поведение в C ++ состоит в том, чтобы сначала выбрать «наиболее специализированную» перегрузку (из базовых шаблонов). Следующий шаг - проверить, является ли выбранная перегрузка явно специализированной. Если это так, будет выбрана явная специализация, которая соответствует.

Не могли бы вы указать место в стандарте, которое определяет второй шаг (выделенная часть в предыдущем абзаце)?

Спасибо.

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

Если я вас правильно понимаю, возможно, вы ссылались на это из [temp.inst§4] :

Если специализация шаблона функции не была явно задана или явно специализирована, шаблон функции специализация неявно создается , когда специализация ссылка в контексте, который требует определения функции для существования или если наличие определения влияет на семантику программа [...]

Что в порядке отрицания говорит о том, что явная специализация получает приоритет.

0 голосов
/ 11 сентября 2018

Стандарт не определяет формально, что такое явная специализация.Наиболее релевантная часть, которую я могу найти, это пример в [temp.expl.spec] / 1:

[Пример:

template<class T> class stream;

template<> class stream<char> { /* ... */ };

template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v) { /* ... */ }

template<> void sort<char*>(Array<char*>&);

Учитывая этиобъявлений, stream<char> будет использоваться в качестве определения потоков char с;другие потоки будут обрабатываться специализациями шаблонов классов, созданными из шаблона класса.Аналогично, sort<char*> будет использоваться в качестве функции сортировки для аргументов типа Array<char*>;другие типы Array будут отсортированы по функциям, сгенерированным из шаблона.- конец примера]

0 голосов
/ 11 сентября 2018

Из рабочего проекта (N4713):

17.6.6.2 Частичное упорядочение шаблонов функций [temp.func.order]
1. Если шаблон функцииперегружен, использование специализации шаблона функции может быть неоднозначным, поскольку вычет аргумента шаблона может связать специализацию шаблона функции с более чем одним объявлением шаблона функции.Частичное упорядочение объявлений шаблонов перегруженных функций используется в следующих контекстах для выбора шаблона функции, к которому относится специализация шаблона функции:
(1.1) - при разрешении перегрузки для вызова специализации шаблона функции;
(1.2) - когда берется адрес специализации шаблона функции;
(1.3) - когда удаляется оператор размещения, который является специализацией шаблона функции, для соответствия новому оператору размещения;
(1.4) - когда другОбъявление функции, явная реализация или явная специализация относится к специализации шаблона функции.

Также:

2 Частичное упорядочение выбирает, какой из двух шаблонов функций является более специализированным, чем другой, путем преобразования каждого шаблона по очереди (см. Следующий абзац) ивыполнение вывода аргумента шаблона с использованием типа функции. Процесс удержания определяет, является ли один из шаблонов более специализированным, чем другой . Если это так, то более специализированный шаблон выбирается в процессе частичного упорядочения.Если оба вывода успешны, частичное упорядочение выбирает более ограниченный шаблон, как описано в правилах в 17.4.4.

17.6.5.2 Частичное упорядочение специализаций шаблона класса [temp.class.order]
1 Для двух частичных специализаций шаблонов классов первый более специализирован, чем второй, если, учитывая следующее переписывание двух шаблонов функций, первый шаблон функции более специализирован, чем второй, в соответствии с правилами упорядочения для шаблонов функций (17.6.6.2): ​​(1.1) - Каждый из двух шаблонов функций имеет те же параметры шаблона и связанные ограничения (17.4.2), что и соответствующая частичная специализация.
(1.2) - Каждый шаблон функции имеет одинпараметр функции, тип которой является специализацией шаблона класса, где аргументы шаблона - это соответствующие параметры шаблона из шаблона функции для каждого аргумента шаблона в списке аргументов шаблона простого идентификатора шаблона частичного объекта.cialization .
2 [Пример:

template<int I, int J, class T> class X { };
template<int I, int J> class X<I, J, int> { }; // #1
template<int I> class X<I, I, int> { }; // #2
template<int I0, int J0> void f(X<I0, J0, int>); // A
template<int I0> void f(X<I0, I0, int>); // B

template <auto v> class Y { };
template <auto* p> class Y<p> { }; // #3
template <auto** pp> class Y<pp> { }; // #4
template <auto* p0> void g(Y<p0>); // C
template <auto** pp0> void g(Y<pp0>); // D

Согласно правилам упорядочения для шаблонов функций, шаблон функции B является более специализированным, чем шаблон функции A и шаблон функции Dявляется более специализированным, чем шаблон функции C. Следовательно, частичная специализация # 2 является более специализированной, чем частичная специализация # 1, а частичная специализация # 4 является более специализированной, чем частичная специализация # 3.- конец примера]

[Пример:

template<typename T> concept C = requires (T t) { t.f(); };
template<typename T> concept D = C<T> && requires (T t) { t.f(); };
template<typename T> class S { };
template<C T> class S<T> { }; // #1
template<D T> class S<T> { }; // #2
template<C T> void f(S<T>); // A
template<D T> void f(S<T>); // B

Частичная специализация # 2 более специализирована, чем # 1, потому что B более специализирован, чем A .- конец примера]

...