This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 119a. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2025-12-20
[Voted into WP at October 2005 meeting.]
Is the following well-formed?
class policy {}; class policy_interface {}; template <class POLICY_INTERFACE> class aph { protected: typedef POLICY_INTERFACE PI; }; template <class POLICY, class BASE, class PI = typename BASE::PI> class ConcretePolicyHolder : public BASE, protected POLICY {}; ConcretePolicyHolder < policy , aph < policy_interface > > foo; void xx() { }The issue is whether the access to the default argument type BASE::PIis checked before or after it is known that BASE is a base class ofthe template. To some extent, one needs to develop the list oftemplate arguments (and therefore evaluate the default argument)before one can instantiate the template, andone does not know what base classes the template has until it hasbeen instantiated.
Notes from April 2003 meeting:
Shortened example:
class B { protected: typedef int A; }; template<class T, class U = typename T::A> class X : public T { };The convincing argument here is that if we had only the declarationof the template (including the default argument), we would expectit to be usable in exactly the same way as the version with thedefinition. However, the special access needed is visible onlywhen the definition is available. So the above should be an error,and information from the definition cannot affect the access ofthe default arguments.
Proposed Resolution (April 2003):
Add a new paragraph 16 to 13.2 [temp.param] afterparagraph 15:
Since a defaulttemplate-argument is encountered before anybase-clause there is no special access to members used in a defaulttemplate-argument.[Example: class B {}; template <class T> class C { protected: typedef T TT; }; template <class U, class V = typename U::TT> class D : public U {}; D <C<B> > d; // access error, C::TT is protected--- end example]Notes from October 2003 meeting:
We decided that template parameter default arguments shouldhave their access checked in the context where they appearwithout special access for the entity declared (i.e., they aredifferent than normal function default arguments). One reason:we don't know the instance of the template when we need thevalue. Second reason: compilers want to parse and throw away theform of the template parameter default argument, not save it andcheck it for each instantiation.
Class templates should be treated the same as function templatesin this regard. The base class information is in the same categoryas friend declarations inside the class itself -- not available.If the body were used one would need to instantiate it in orderto know whether one can name it.
Proposed resolution (October, 2004):
Add the following as a new paragraph following the lastparagraph of 11.8 [class.access] (but before the newparagraph inserted by the resolution ofissue 372, if adopted):
The names in a defaulttemplate-argument (13.2 [temp.param]) have their access checked in the context in whichthey appear rather than at any points of use of the defaulttemplate-argument. [Example:
class B {}; template <class T> class C { protected: typedef T TT; }; template <class U, class V = typename U::TT> class D : public U {}; D <C<B> >* d; // access error, C::TT is protected—end example]