Статическое определение шаблона и ошибки явной специализации в MSVC

Мне интересно, почему следующий код прекрасно работает в gcc

#include <iostream>
using namespace std;

template<typename T>
struct F {
static T const value;
};

template<>
struct F<int> { // Specialization
static int const value;
};

template struct F<int>;

template<typename T>
T const F<T>::value = sizeof(T);

template<>
int const F<int>::value = 42;

int main() {

struct F<int> ma;
cout << ma.value;

return 0;
}

http://ideone.com/wvrurz

в то время как на MSVC 2012 я не могу заставить его скомпилировать:

#include <iostream>
using namespace std;

template<typename T>
struct F {
static T const value;
};

template<>
struct F<int> { // Specialization
static int const value;
};

//template struct F<int>; // error C2950: 'F<int>' : cannot explicitly instantiate an explicit specialization

template<typename T>
T const F<T>::value = sizeof(T);

//template<>
//int const F<int>::value = 42; // error C2998: 'const int F<int>::value' : cannot be a template definition

int main() {

struct F<int> ma;
cout << ma.value;

return 0;
}

Из того, что я прочитал в n3242 §14.7 5

и явное создание и объявление явного
специализация не должна появляться в программе, если явно
инстанцирование следует за декларацией явной специализации.

и я считаю, что это так. Я что-то пропустил?

10

Решение

СЛИШКОМ ДОЛГО; Не читал

  • MSVC 2012 правильно отклоняет строку, помеченную // error C2998,

  • первая диагностика, однако, ошибочна и должна быть принята; как это в новые версии компилятора.

Заметка: Отчет об ошибках, связанных с C2950 можно найти, Вот.


относительно C2950

MSVC 2012 неправильно выдавать диагностику для рассматриваемой линии.

template<class T> struct A;

template<>
struct A<int> { };

template struct A<int>; // legal

int main () { }

Стандарт гласит, что явная реализация должна содержать простой шаблон-идентификатор, что именно A<int> есть, и с этим сказал; это правовой C ++.

14.6.2p3 Явная реализация [temp.explicit]

Если явное создание экземпляра для класса или класса-члена, уточненный тип Спецификатор в декларация должен включать в себя простой шаблон-идентификатор.

14.2p1 Названия шаблонных специализаций [temp.names]

Специализация шаблона (14.7) может быть упомянута Шаблон-идентификатор:

simple-template-id:
template-name < template-argument-list_opt >

Изменение формулировки: C ++ 03 против C ++ 11

14.7.2p5 есть новая формулировка, начиная с C ++ 11, который был введен в действие после следующего отчет о дефектах:

14.7.2p5 Явная реализация [temp.explicit]

Для заданного набора аргументов шаблона, если явное создание шаблона появляется после объявления явной специализации для этого шаблона, явное создание экземпляра не имеет никакого эффекта.

Заметка: Слава @DYP для привлечения внимания к ранее связанному DR.


относительно C2998

Эта ошибка точна; вы не имеете в виду что-то, что зависит от параметра-шаблона, это означает, что вы не должны использовать template<> на определение в вопросе.

Более новые версии gcc выдает диагностику относительно этого, и лязг правильно отвергает такое определение.

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<>синтаксис. То же самое верно при определении члена явно специализированного класса члена.

8

Другие решения


По вопросам рекламы [email protected]