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