javaLover
javaLover

Reputation: 6425

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++.)

Upvotes: 4

Views: 276

Answers (1)

songyuanyao
songyuanyao

Reputation: 172994

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

Upvotes: 4

Related Questions