How to allow the method of access to private members of other instances of the template class?

This extremely minimal example does not compile since A<int> cannot access private member i in A<double>

 template <class T> class A { int i; public: template <class U> void copy_i_from( const A<U> & a ){ i = ai; } }; int main(void) { A<int> ai; A<double> ad; ai.copy_i_from(ad); return 0; } 

I know that I can make all template instances friends of each other (see How to access private members of other template class instances? ), But since I have only one method that requires access (as in the example), I would prefer limit friendship by this method. Is it possible?

+8
c ++ private-members templates
source share
2 answers

Yes it is possible. Member functions can be designated as friends usually.

 template <class T> class A { int i; public: template <class U> void copy_i_from( const A<U> & a ){ i = ai; } template <class F> template <class U> friend void A<F>::copy_i_from(const A<U> & a); }; int main(void) { A<int> ai; A<double> ad; ai.copy_i_from(ad); return 0; } 

Live example (gcc one Ideone)


Note that unlike gcc, clang rejects the code . I can not find anything in the standard that would make it invalid.

+8
source share

It seems that if you want to have a friend-member function, the following will not work in clang :

 template <class T> class A { int i; public: template <class U> void copy_i_from( const A<U> & a ){ i = ai; } template <class F> template <class U> friend void A<F>::copy_i_from(const A<U> & a); }; int main(void) { A<int> ai; A<double> ad; ai.copy_i_from(ad); return 0; } 

while it works on gcc .

The problem is the clang problem with the presentation of the friends class template for which the dependent name specifier cannot be resolved in AST: http://llvm.org/klaus/clang/commit/8b0fa5241a0416fc50dfbb7e38f20e777f191848/ (still in the trunk at the time of writing this).

Therefore, you can upgrade to the version of the member function above, although this may not work on clang until it becomes clear.

Plan-B's solution is to have a friend’s free template function, although this may not be what you want (accepted by both cland and gcc):

 #include <iostream> using namespace std; template <class T> class A { int i; public: template<class V, class U> friend void copy_i_from(A<V>& t, const A<U> & a); }; template<class V, class U> void copy_i_from(A<V>& t, const A<U> & a){ ti = ai; } int main(void) { A<int> ai; A<double> ad; copy_i_from(ai,ad); return 0; } 

Example

+6
source share

All Articles