Ответ 1
Ваш пример
Если вы ошибаетесь, я бы назвал теперь удаленный ответ
Если я не ошибаюсь, это противоречит [temp.deduct.guide] p3:
Идентификатор простого шаблона должен указывать специализацию шаблона класса.
TT<std::string>
не указывает специализацию шаблона класса, а ваш код плохо сформирован.Существует также это в [temp.spec] p4:
Специализация - это класс, функция или член класса, который либо создан, либо явно специализирован.
TT
является технически параметром типа шаблона. Конструкция TT<std::string>
является зависимым от типа именем типа. Если руководство по удержанию будет фактическим шаблоном функции, и мы его создадим, TT<std::string>
может быть создан как имя класса, относящееся к специализации шаблона класса. Он также может ссылаться на int
, если TT
создается для ссылки на подходящий шаблон-псевдоним. Но как есть, в объявлении-указателе дедукции он еще не назвал специализацию шаблона класса.
В [temp.res] p8.5.5 существует правило:
В противном случае для шаблона, для которого может быть создана действительная специализация, не выдаётся никакой диагностики.
Итак, может ли вообще быть специализация гида-гида? Я утверждаю, что нет. Прежде всего, это не "шаблонный объект" (c.f. [temp] p8), который может быть создан. То, что специализируется в выводе аргумента шаблона шаблона, представляет собой набор шаблонов, которые формируются на основе руководств по вычитанию, но не самими направляющими. См. [Over.match.class.deduct] p1.4
[...] Для каждого гида-указателя создается шаблон функции или функции со следующими свойствами [:]: [...]
Это те шаблоны функций, которые дополнительно специализируются в процессе перегрузки. Вывод руководства сам по себе никогда не специализируется, поэтому мы можем создать диагностическое сообщение о нарушении правила, согласно которому простой шаблон-идентификатор в руководстве по вычитанию не называет специализацию шаблона класса.
Именование по шаблону псевдонима (пример Ричарда)
Ричард дал другой пример
template<typename T> class X { T t; };
template<typename T> using Y = X<T*>;
template<typename T> Y(T) -> Y<T>;
В этом случае это сложнее, и я думаю, что это может быть разрешено формулировкой, так как Y<T>
на самом деле является специализацией шаблона класса. Теперь вы можете спорить о том, на самом деле ли он называет специализацию или просто обозначает ее, после применения правил перезаписи. Тот факт, что он может допускать аргументы, кажется достаточным, чтобы гарантировать отчет о дефектах, IMO.