Специализация шаблонного класса как структуры - PullRequest
17 голосов
/ 21 февраля 2012

Я чуть более специализировался std::hash для пользовательского типа, используя:

template<>
struct hash<...> {...};

Когда VC10 приветствовал меня с предупреждением:

предупреждение C4099: 'std :: hash <_Kty>': имя типа, впервые увиденное с использованием 'class' теперь видно с использованием 'struct'

и я обнаружил, что ее стандартная библиотека объявляет std::hash как class, тогда как стандарт (или последний свободный черновик, который у меня есть) объявляет его как struct.

Ну, конечно, я знаю, что структура ничем не отличается от класса (за исключением разных типов доступа по умолчанию и типов наследования). Но мои вопросы:

  1. В данном случае VC10 нарушает стандарт или имеет право свободно обменивать struct s на class s в любых компонентах стандартной библиотеки (если, конечно, требуемые типы доступа для членов остаются согласованными),
  2. Допустимо ли специализировать шаблонный класс как структуру и наоборот, или это вызывает проблемы с разрешением имен и т. П. (По крайней мере, VC10 считает, что это стоит предупреждения).

Ответы [ 2 ]

8 голосов
/ 21 февраля 2012

Во-первых, вот ответ на 2. взят из 14.5.1 [temp.class] параграф 4:

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

Однако struct и class ссылаются на один и тот же ключ класса в соответствии с 7.1.6.3 [dcl.type.elab] пункта 3 последнего предложения:

Ключевое слово class-key или enum, присутствующее в подробном спецификаторе типа, должно в натуре согласовываться с объявлением, на которое ссылается имя в подробном спецификаторе типа. [...] Таким образом, в любом разработанном спецификаторе типа ключевое слово enum должно использоваться для ссылки на перечисление, ключ класса объединения должен использоваться для ссылки на объединение, а также ключ класса или структуры class-key должен использоваться для ссылки на класс, объявленный с использованием class или struct class-key.

Пробуя g ++, clang и EDG, все соглашаются, что можно специализировать шаблон, объявленный как struct как class. Однако clang предупреждает об изменении с struct на class или наоборот. Исходя из этого, стандартная библиотека может свободно выбирать любое ключевое слово, которое она считает подходящим для определения. Очевидно, что если компилятор отклоняет код в результате, что-то серьезно нарушается, но я думаю, что в данном случае это не библиотека, а компилятор.

0 голосов
/ 21 февраля 2012

Для 1: я не уверен, но считаю, что это ошибка.

Для 2: не волнуйтесь, это не должно приводить к каким-либо странным действиямПросто будьте осторожны с областями функций, которые вы определяете.Что касается предупреждения, оно на самом деле довольно общее (то есть не особенно сделано для шаблонов), поэтому мне было бы все равно.* этот вопрос, который в основном говорит о том, что он не имеет никакого значения в стандарте, но некоторые компиляторы могут вести себя странно.

...