3

The code bellow compiles without a warning on GCC and issues an error with clang (any c++11 compatible versions of both clang and GCC). Which compiler is right with respect to the standard? Specifically, is it allowed to declare as friend a non partially specialized template alias which is a partial template specialization of a class?

This makes me think that it might not be allowed:

  1. cppreference says: "Friend declarations cannot refer to partial specializations [...]".
  2. And also: "A type alias declaration introduces a name which can be used as a synonym for the type denoted by type-id. It does not introduce a new type [...]".
  3. Finally: "Both function template and class template declarations may appear with the friend specifier [...]". It implicitly excludes the possibility for a template alias to be a friend of a class as an actual template alias but rather as the aliased class template, which is a partial specialization in the snippet bellow.

However, this makes me think that it might be allowed:

  1. cppreference says : "An alias template is a template [...]". I undestand that a template alias is a distinct template. By consequence, declaring it as friend as in the following example without partial specilization of the class template alias is valid... Or not.
  2. This code (not from me) also gives a workaround and let me think that there is no obvious reason for making the following code ill-formed.

This post asks a very similar question but no clear answer was provided with respect to the specific usage of an intermediate template alias.

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;
};

Intent: legal way to declare a partial specialization as friend using an intermediate alias (workaround).

Result: GCC is happy with it and produces the intended behaviour. Clang produces the following error:

<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>;
Meatboy 106
  • 196
  • 7

0 Answers0