Было бы неплохо, если бы этот код был неверным. Но это концептуально звучит, и GCC принимает его , хотя Comeau этого не делает:
template< typename > struct t;
template<> struct t< int > {} r; // Bad declarator! Don't pee on the carpet!
( Редактировать: вышеприведенные компиляции, но r
кажется, не объявляется в любой области , так что это по существу игнорируется.)
Явные специализации заполняют некую область между шаблонами и классами. Тип, объявленный явной специализацией, завершается после его определения. С точки зрения компилятора, это не шаблон. Если бы это был параметризованный шаблон, объявление объекта было бы невозможно. Рассмотрим §14 / 3:
В объявлении шаблона, явной специализации или явном создании список инициаторов объявления в объявлении должен содержать не более одного декларатора. Когда такое объявление используется для объявления шаблона класса, объявление не допускается.
Что означает «используется для объявления шаблона класса»? Понятно, что основной шаблон объявляет шаблон класса. И частичная специализация тоже, согласно §14.5.5 / 1 (номера FDIS):
Объявление шаблона, в котором имя шаблона класса представляет собой простой-идентификатор шаблона, является частичной специализацией шаблона класса, указанного в простом-шаблоне-идентификаторе.
Однако, когда дело доходит до явных специализаций, Стандарт говорит в терминах декларации, которой предшествует последовательность токенов template<>
. Он выглядит как шаблон и называет имя шаблона, но, похоже, он не объявляет шаблон.
Действительно странной вещью является то, что §14 / 3 ограничивает количество объявлений до «не более одного». Объявление шаблона функции, явная специализация или создание должны иметь ровно один декларатор. Любое объявление, включающее шаблон класса, должно иметь ровно ноль ... кроме явной специализации, которая, похоже, проваливается. К счастью, GCC отказывается разрешить
template<> struct t< int > {} r, s; // Offer valid one per specialization.
Я склонен согласиться с интерпретацией GCC, чушь, как это может быть. К сожалению, это может ингибировать его способность обнаруживать пропущенные точки с запятой. Пожалуйста, пусть количество разрешенных деклараторов будет точно равно нулю!