Шаблон явной реализации (определение и объявление) в gcc [duplicate]

0

Предположим, что есть такой код:

template <typename T>
CLASS_KEY1 X{};

PREFIX template CLASS_KEY2 X<int>;

где CLASS_KEY1, CLASS_KEY2 и PREFIX - это макросы. CLASS_KEY1 и CLASS_KEY2 могут быть расширены до ключевых слов class, struct или union. PREFIX может быть расширен до пустого набора символов или ключевого слова extern.

Вот таблица, которая показывает, когда такой код компилируется (Yes - компилирует, No - не компилирует) для всех комбинаций значений макросов (компилятор gcc-4.8.1, опция -std=c++11):

PREFIX                                        extern  extern  extern
CLASS_KEY1\CLASS_KEY2 class   struct  union   class   struct  union
class                 Yes     Yes?    No      Yes     Yes?    No
struct                Yes?    Yes     No      Yes?    Yes     No
union                 No      No      Yes     No      No      Yes

Это ошибка в gcc или стандартном требовании (странные случаи помечены вопросительными знаками)? А как насчет других компиляторов?

  • 0
    Appart из политики инкапсуляции, нет никакой разницы между struct и class . Могу поспорить, что сохраненная политика объявлена, когда класс определяется.
  • 0
    Однако clang ++ выдает предупреждение, когда вы пытаетесь это сделать: warning: class template 'X' was previously declared as a struct template . Оба компилятора применяют политику инкапсуляции, объявленную там, где определен класс.
Показать ещё 1 комментарий
Теги:
c++11
templates
gcc
explicit-instantiation

1 ответ

2
Лучший ответ

Раздел 7.1.6.3 (спецификаторы специфицированного типа) стандарта С++ 11 гласит:

Ключевое слово класса или enum присутствующее в специфицированном спецификаторе типа, должно согласовываться в натуральной форме с объявлением, к которому относится имя в спецификаторе разработанного типа. Это правило также относится к форме специфицированного спецификатора типа, объявляющего класс-имя или класс friend поскольку это может быть истолковано как относящееся к определению класса. Таким образом, в любом специфицированном спецификаторе типа ключевое слово enum должно использоваться для ссылки на перечисление (7.2), ключ класса union должен использоваться для ссылки на union (раздел 9) и class или struct -key должен использоваться для обозначения class (пункт 9) объявляется с помощью class или struct класса ключа.

Таким образом, поведение, которое вы видите, разрешено.

  • 0
    Спасибо за эту цитату.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню