Search code examples
c++templatesfriend

How to friend with a template (alias) class defined by "template using"?


Class B<certain X> wants to be a friend with every C<any,certain X>.
I am pulling my hair out to find how to do it.

Below is the full code that successfully compiles as long as I don't add the problematic line.

#include <string>
using namespace std;

enum EN{ EN1,EN2 };
template<EN T1,class T2> class C{
    public: C(){
        std::cout<<T1<<std::endl;   
    }
};
template<class T2> class B{
    template<EN T1> using CT = C<T1,T2>;
    //template<EN TX> friend class CT;  //<-- error if insert this line
    public: static void test(){
        CT<EN1> ct;
    }
};

int main() {
    B<int>::test();
    return 0;
}

Here are what I tried (all fail):-

template<EN T1> friend class C<T1,T2>;  
template<EN TX> friend class CT;  
template<typename TX> friend class CT; 
template<class TX> friend class CT; 
template<class TX> friend class CT<TX>;    
template<typename> friend typename CT; 

Question: What is the correct statement (1-line) to be inserted?
If possible, I want the friend statement to use CT rather than C.

I have read a similar question and this, but they are simpler than mine.
(I am new to C++.)


Solution

  • Class B wants to be a friend with every C.

    Unfortunately it's impossible, because template friend cannot refer to partial specializations. And this issue has nothing to do with using.

    Friend declarations cannot refer to partial specializations, but can refer to full specializations

    You can use full specilizations as workaround, if enum EN doesn't have much enumerators. e.g.

    template<class T2> class B {
        template<EN T1> using CT = C<T1, T2>;
        friend CT<EN1>; // same as friend C<EN1, T2>;
        friend CT<EN2>; // same as friend C<EN2, T2>;
        ...
    };