#cpp #история
Почему для объявления полной специализации шаблонного класса используется синтаксис template<>? Зачем он нужен, если можно использовать просто название класса со специализируемыми типами?
Ответы
Ответ 1
В С++ синтаксис template<> class SomeClass<аргументы> объявляет совершено новую сущность - явную специализацию шаблонного класса. Хоть явная специализация и имеет связь с "главным" шаблоном, ее содержимое (определение) является совершенно независимым от главного шаблона. А синтаксис class SomeClass<аргументы> просто ссылается на уже существующую сущность - на специализацию какого-то уже объявленного шаблонного класса SomeClass для данного набора аргументов. У этих синтаксисов совершено разные цели: объявление новой сущности vs. ссылка на уже ранее объявленную сущность. Также, когда речь идет об объявлениях специализаций членов классов, наличие или отсутствие template <> также приводит к серьезным различиям в интерпретации таких объявлений (хотя суть различия остается та же). См. https://ru.stackoverflow.com/a/934161/182825 Тут можно попытаться изобрести какой-то набор автоматических правил, которые, возможно, позволили бы компилятору самому разобраться, что именно мы хотим сделать в каждом конкретном контексте. Однако в С++ традиционно введение новых сущностей делается явно и для этого выделен отдельный синтаксис объявления. Для явных специализаций этот отдельный синтаксис - это именно синтаксис начинающийся с template <>.Ответ 2
Изначально полную специализацию действительно объявляли без template<>, т.е. templatestruct A { }; struct A { }; , однако в стандарт вошёл именно вариант с template<> из-за неоднозначностей (ambiguities) в более сложных случаях полных специализаций. Например: // №1 template struct A { template struct B { static int x; }; }; // №2 template<> template struct A ::B { static unsigned x; }; // №3 template<> template<> unsigned A ::B ::x; // №4 template<> struct A { template struct B { static long x; }; }; // №5 template<> long A ::B ::x; Здесь №2 - специализация члена шаблонного класса A для типа unsigned, №4 - полная специализация шаблонного класса A для типа long, №3 - специализация члена шаблонного класса A ::B для типа unsigned, №5 - то же, что и №3 для типов long, но так как присутствует полная специализация №4, в №5 только 1 template<> в отличие от 2 template<> в №3. Если бы template<> отсутствовали, то специализации №3 и №5 были бы неотличимы.
Комментариев нет:
Отправить комментарий