Created on 2007-07-06.00:00:00 last changed 179 months ago
[Voted into WP at March, 2010 meeting.]
Proposed resolution (October, 2009):
Change 13.7.5 [temp.friend] paragraph 5 as follows:
A member of a class template may be declared to be a friend of a non-template class. In this case, the corresponding member of every specialization of the class template is a friend of the class granting friendship. For explicit specializations the corresponding member is the member (if any) that has the same name, kind (type, function, class template or function template), template parameters, and signature as the member of the class template instantiation that would otherwise have been generated. [Example:
template<class T> struct A { struct B { }; void f(); struct D { void g(); }; }; template<> struct A<int> { struct B { }; int f(); struct D { void g(); }; }; class C { template<class T> friend struct A<T>::B; // grants friendship to A<int>::B even though // it is not a specialization of A<T>::B template<class T> friend void A<T>::f(); // does not grant friendship to A<int>::f() // because its return type does not match template<class T> friend void A<T>::D::g(); // does not grant friendship to A<int>::D::g() // because A<int>::D is not a specialization of A<T>::D };
Notes from the July, 2009 meeting:
The consensus of the CWG was to allow the correspondence of similar members in explicit specializations.
Is this code well-formed?
template <typename T> struct A { struct B; }; class C { template <typename T> friend struct A<T>::B; static int bar; }; template <> struct A<char> { struct B { int f() { return C::bar; // Is A<char>::B a friend of C? } }; };
According to 13.7.5 [temp.friend] paragraph 5,
A member of a class template may be declared to be a friend of a non-template class. In this case, the corresponding member of every specialization of the class template is a friend of the class granting friendship.
This would tend to indicate that the example is well-formed. However, technically A<char>::B does not “correspond to” the same-named member of the class template: 13.9.4 [temp.expl.spec] paragraph 4 says,
The definition of an explicitly specialized class is unrelated to the definition of a generated specialization. That is, its members need not have the same names, types, etc. as the members of a generated specialization.
In other words, there are no “corresponding members” in an explicit specialization.
Is this the outcome we want for examples like the preceding? There is diversity among implementations on this question, with some accepting the example and others rejecting it as an access violation.
History | |||
---|---|---|---|
Date | User | Action | Args |
2010-03-29 00:00:00 | admin | set | messages: + msg2735 |
2010-03-29 00:00:00 | admin | set | status: ready -> cd2 |
2009-11-08 00:00:00 | admin | set | messages: + msg2375 |
2009-11-08 00:00:00 | admin | set | status: drafting -> ready |
2009-08-03 00:00:00 | admin | set | messages: + msg2202 |
2009-08-03 00:00:00 | admin | set | status: open -> drafting |
2007-07-06 00:00:00 | admin | create |