Шаблон псевдонима друга не компилируется с Clang - PullRequest
3 голосов
/ 12 апреля 2019

Код ниже компилируется без предупреждения на GCC и выдает ошибку с clang (любые c ++ 11-совместимые версии clang и GCC).Какой компилятор прав по отношению к стандарту?В частности, разрешено ли объявлять в качестве друга не частично специализированный шаблонный псевдоним, который является частичной шаблонной специализацией класса?

Это заставляет меня думать, что это не может быть разрешено:

  1. cppreference говорит: " Объявления друзей не могут ссылаться на частичные специализации [...]".
  2. А также: «Объявление псевдонима типа вводит имя, которое может использоваться как синоним для типа, обозначаемого идентификатором типа. Оно не вводит новый тип [...] ".
  3. Наконец:" И шаблон функции и объявления шаблона класса могут появляться с указателем друга [...] ".Это неявно исключает возможность того, что псевдоним шаблона может быть другом класса в качестве фактического псевдонима шаблона, а не в качестве шаблона псевдонима класса, что является частичной специализацией в приведенном ниже фрагменте.

Однакоэто заставляет меня думать, что это может быть разрешено:

  1. cppreference говорит: " Шаблон псевдонима - это шаблон [...]".Я понимаю, что псевдоним шаблона - это отдельный шаблон.Следовательно, объявление его в качестве друга, как в следующем примере, без частичной спецификации псевдонима шаблона класса, допустимо ... Или нет.
  2. Этот код (не от меня) также даетОбходной путь и позвольте мне думать, что нет никаких очевидных причин для того, чтобы сделать следующий код некорректным.

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

template<typename T,typename N> class B{};

template<typename T> class A{
    // template<typename U> friend class B<T,U>; fails as expected
    template<typename N> using alias = B<T,N>;
    template<typename N> friend class alias;
};

Намерение: законный способ объявить частичную специализацию другом, используя промежуточный псевдоним (обходной путь).

Результат: GCC доволенэто и производит намеченное поведение.Clang выдает следующую ошибку:

<source>:7:35: error: redefinition of 'alias' as different kind of symbol

template<typename N> friend class alias;
                                  ^
<source>:6:22: note: previous definition is here

template<typename N> using alias = B<T,N>;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...