2016-01-11 1 views
3

n4567 [temp.class.spec.match] p2Каких правила применяются, когда аргумент частичной специализации не использует какие-либо из его параметров шаблона

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

template<class T, class U> 
struct S{}; 

template<class U> 
struct S<int, U>{}; 

S<char, int> s; 

Я знаю, что частичная специализация S<int, U> не совпадает со списком аргументов шаблона фактической char, int, а второй аргумент U можно вывести Фром int accroding в 14.8.2.5.

Но я не знаю, какие правила в 14.8.2 применяются к первому аргументу int.

14.8.2.5 [temp.deduct.type] p1

аргументы шаблона могут быть выведены в нескольких различных контекстах, но в каждом случае типа, который указан в терминах параметров шаблона (назовем его P) сравнивается с фактическим типом (назовем его A), и делается попытка найти значения аргументов шаблона (тип для параметра типа, значение для параметра не-типа или шаблон для параметра шаблона), который будет делать P, после подстановки выведенных значений (назовем его выведенным A), совместимым с A ,

В моем понимании int в S<int, U> является не определены в терминах параметров шаблона, так 14.8.2.5 делает не применять.

Я хочу знать, какие правила обрабатывать этот случай или вы можете исправить меня о 14.8.2.5


Другими словами: Наглядно частичная специализация S<int, U> не соответствует char,int, потому что char не соответствует int ,

Я хочу знать, какие правила определяют char не соответствует int.

+0

Что вы на самом деле спрашиваете? – Barry

+0

Кроме того, вы, похоже, довольно существенно изменили содержание вопроса, так как получили ответ ... – Barry

ответ

0

При рассмотрении того, что здесь происходит:

template<class T, class U> struct S{}; // (1) 
template<class U> struct S<int, U>{}; // (2) 

S<char, int> s; // (1) or (2)? 

Чтобы определить, какой специализации мы используем для s, мы идем в [temp.class.spec.match]:

Когда шаблон класса используемый в контексте, который требует создания экземпляра класса, необходимо, чтобы определяло, будет ли создание экземпляра сгенерировано с использованием первичного шаблона или одной из частных специализаций . Это делается путем сопоставления аргументов шаблона специализации шаблона класса с списками шаблонов шаблонов для частичных специализаций.

В этом случае мы соответствие <char, int> против <int, U>. Что означают совпадения?

Частичная специализация соответствует заданному фактическому шаблону список аргументов, если аргументы шаблона частичной специализации может быть выведены из фактического списка аргументов шаблона (14.8.2).

В основном, мы выводя U соответствовать int == char и U == int. Эквивалентные мы смотрим на выведении U в:

template <class U> void f(S<int, U>); 
f(S<char, int>{}); 

Там нет такого вычета.

Это приводит нас к:

- Если совпадений не найдено, то конкретизация генерируется из основного шаблона.

Это приводит нас к (1).

Давайте более интересный случай:

S<int, char> s2; 

Теперь <int, char> матчи против <int, U>, потому что мы можем вывести U=char. Следовательно:

- Если найдена только одна соответствующая специализация, экземпляр создается из этой специализации.

Это приводит нас к (2).

+0

Каждый вывод имеет' A' и 'P', что они для 'S ' Соответствие 'S '? – stackcpp

+0

@stackcpp 'P' is' S '. 'A'' 'S '. – Barry

+0

Это имеет смысл. В стандарте говорится: «Если аргументы ** шаблона ** частичной специализации могут быть выведены из фактического списка аргументов шаблона, я думал, что' A' был 'int', а' P' был 'U', вывод для' U' удался, но матч терпит неудачу, поэтому я задал этот вопрос. – stackcpp

4

В моем понимании int в S не указывается в терминах параметров шаблона, поэтому 14.8.2.5 не применяется.

Нет, 14.8.2.5 объясняет как вывести тип, 14.3 сделки с аргументами шаблона и кода вы публикуемую терпит неудачу 14.3p1:

14.3p1 ... Тип и форма каждого template-argument, указанный в идентификаторе шаблона, должен соответствовать типу и форме, указанным для соответствующего параметра, объявленного шаблоном в его списке параметров шаблона.

template<class T, class U> 
struct S<int, U> {}; 
// compiler error, template parameters not used in partial specialization 

должен быть

template<class U> 
struct S<int, U> {}; 

Так,

#1 
template<class T, class U> 
struct S{}; 

#2 
template<class U> 
struct S<int, U> {}; 

S<char, int> s; // uses #1 
S<int, char> c; // uses #2 since S<int, U> matches more closely than S<T, U> 

Вы упоминаете, что gcc отклонил шаблон, а clang принял его. В моих тестах VC++ и gcc предоставили ошибку компилятора по умолчанию и вообще не компилировали код, clang, однако, вместо этого указали, что this partial specialization will never be used и все равно построили двоичный файл. Таким образом, во всех случаях он уведомляет о несоответствии, это просто вопрос о том, какие параметры компилятора включены по умолчанию и как реализация компилятора обрабатывает несоответствующий код.

Надеюсь, что это поможет.

+0

@stackcpp, да, извините, скопируйте-pasta'd неправильный раздел. Должно быть, '14.3'. Много разделов перекрестно ссылаются друг на друга, и иногда разделы нужно читать не по порядку, чтобы их можно было читать по порядку:/ – txtechhelp

Смежные вопросы