C++ Templates: Partial Template Specifications and Friend Classes
c++, friend-class, partial-specialization, template-specialization, templates
Solution
In C++, you can grant access beyond `private` on four levels.
- completely `public` access (see pmr's answer)
- access within inheritance hierarchy (`protected`, irrelevant here)
- to a base template `friend` (see this answer)
- to a non-template or fully specialized `friend` (too weak to solve your use case)
There is no middle way between the two latter kinds of friendship.
From §14.5.4 of the C++ standard:.
Friend declarations shall not declare partial specializations.
The following declaration will allow you to implement what you need. It gives you a free hand to access any specialization of your template from any other specialization, but still only within `X`. It is slightly more permissive than what you asked for.
template<class T> class X
{
template<class Any> friend class X;
public:
...
};
Problem
is it possible to somehow make a partial template specification a friend class? I.e. consider you have the following template class ``` template <class T> class X{ T t; }; ``` Now you have partial specializations, for example, for pointers ``` template <class T> class X<T*>{ T* t; }; ``` What I want to accomplish is that every possible `X<T*>` is a friend class of `X<S>` for ANY `S`. I.e. `X<A*>` should be a friend of `X<B>`. Of course, I thought about a usual template friend declaration in X: ``` template <class T> class X{ template <class S> friend class X<S*>; } ``` However, this does not compile, g++ tells me this: test4.cpp:34:15: error: specialization of '`template<class T> class X`' must appear at namespace scope test4.cpp:34:21: error: partial specialization '`X<S*>`' declared 'friend' Is this not possible at all or is there some workaround? The reason why I am asking is that I need a constructor in `X<T*>` that creates this class from an arbitrary `X<S>` (`S` must be a subtype of `T`). The code looks like this: ``` template <class T> class X<T*>{ T* t; template<class S> X(X<S> x) : t(&(x.t)) {} //Error, x.t is private } ``` Now, the compiler complains, of course, that `x.t` is not visibile in the constructor since it is private. This is why I need a partial specialization friend class.