This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: c++/3634: partial specialization envolving nested classes is broken

[Get raw message]
At 10:12 19/11/01 +0100, Ewgenij Gawrilow wrote:

> >
> > Synopsis: partial specialization envolving nested classes is broken
> >
> > State-Changed-From-To: open->closed
> > State-Changed-By: lerdsuwa
> > State-Changed-When: Sat Nov 17 00:44:13 2001
> > State-Changed-Why:
> >     Not a bug.  typename outer<T>::inner is a non-deduce context.
> >     The compiler is not allowed to deduce that 'T' is 'int'.  So
> >     the partial specialization is never used by gcc.
> >
>Sorry, I can't agree with this argumentation. There is nothing to deduce
>here. The only thing the compiler has to check is whether the template
>argument is a local class `inner' of ANY instance of a given template class
>`outer'. I think, this could be done without any type deduction,
>since the internal description of `inner' surely contains some kind
>of reference to its containing class.
But it's how specialization works.  To decide which template to use (primary,
partial specialization, specialization), template argument deduction is used.
The rules for that are specified in the C++ standard.
Now, about figuring out the outer class based on the inner class, there is
problem with several such cases.  So the standard chose to disallow it.
Here is an example of problematic case:
   struct A {};
   template <class T> struct outer {
     typedef A inner;
   }
Now 'outer<T>::inner' does not depend on 'T'.  So 'outer<int>::inner' is
the same as 'outer<char>::inner', or 'outer<std::vector<int> >::inner'.
They all refer to the same 'A'.  You cannot tell what 'T' actually is.

>If you forbid partial specializations for local classes, how should
>we write traits classes for iterators, which are most naturally defined
>as local classes of their containers?
The inner class can contain information about its outer class, for example
   template <class T> struct outer {
     struct inner {
       typedef T type;
       typedef outer<T> base;
     };
   };
Then you can obtain 'T' from:
   template<class U> class tmpl {
     public:
       tmpl() { ... /* Can get 'T' from 'typename U::type' */ }
   };

If you have further questions, the best place for the discussion is in
the comp.std.c++ newsgroup.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]