Ответ 1
TOO LONG; НЕ ПРОЧИТАЛ
-
msvc 2012 корректно отклоняет строку с надписью
// error C2998
, -
прежняя диагностика, однако, является ошибочной и должна приниматься; как в более новые версии компилятора.
Примечание. Отчет об ошибке, относящийся к C2950, можно найти, здесь.
Относительно C2950
msvc 2012 неверно выдает диагностику для данной строки.
template<class T> struct A;
template<>
struct A<int> { };
template struct A<int>; // legal
int main () { }
В стандарте указано, что явное инстанцирование должно содержать идентификатор simple-template-id, который является именно тем, что A<int>
, и с указанным; это юридический С++.
14.6.2p3
Явная копия[temp.explicit]
Если явное инстанцирование относится к классу или классу-члену, специфицированный спецификатор типа в объявлении должен содержать идентификатор simple-template-id.
14.2p1
Имена специализированных шаблонов[temp.names]
Специализация шаблона (14.7) может ссылаться на шаблон-id:
simple-template-id: template-name < template-argument-list_opt >
Изменение формулировки: С++ 03 vs С++ 11
14.7.2p5 имеет новую формулировку, начиная с С++ 11, которая была введена после следующего отчета о дефекте:
14.7.2p5
Явная копия[temp.explicit]
Для заданного набора аргументов шаблона, если явное создание шаблона появляется после объявления явной специализации для этого шаблона, явное создание экземпляра не имеет эффекта.
Примечание: Kudos to @dyp для привлечения внимания к ранее связанному DR.
Относительно C2998
Эта ошибка является точной; вы не имеете в виду что-то, что зависит от параметра шаблона, это означает, что вы не должны использовать template<>
для данного определения.
Более новые версии gcc
выдает диагностику по этому поводу, а clang правильно отклоняет такое определение.
template<class T> struct A;
template<>
struct A<int> {
static int const value;
};
template<> int const A<int>::value = 42; // ill-formed, `value` does not depend on
// any template parameter since it's
// explicitly a part of `A<int>`
int main () { }
gcc => foo.cpp:8:22: warning: too many template headers for A<int>::value (should be 0)
clang => foo.cpp:8:1: error: extraneous 'template<>' in declaration of variable 'value'
msvc => foo.cpp(8) : error C2998: 'const int A<int>::value' : cannot be a template definition
Вышеуказанная диагностика верна.
Данная строка является нарушением следующего раздела стандарта:
14.7.3p5
Явная специализация[temp.expl.spec]
Члены явно специализированного шаблона класса определяются так же, как и члены обычного класса, и не используют синтаксис
template<>
. То же самое верно при определении члена явно специализированного класса-члена.