[c++]pt.c:most_specialized_class appears to substitute outer args for inner params

Larry Evans cppljevans@suddenlink.net
Wed Nov 11 14:32:00 GMT 2009


On 11/02/09 22:39, Larry Evans wrote:
> The following code around trunk/gcc/cp/pt.c:15514:
> 
> 15513     partial_spec_args = INNERMOST_TEMPLATE_ARGS (partial_spec_args);
> 15514     partial_spec_args = tsubst_template_args
> 15515       (partial_spec_args, outer_args, tf_none, NULL_TREE);
> 
> as shown here:
> 
> http://gcc.gnu.org/viewcvs/trunk/gcc/cp/pt.c?view=markup&pathrev=153822
> 
> appears to substitute outer_args in the place where inner parameters
> are located.  Am I reading the code wrong?  I ask because gdb seems to
> show this happening with the following code:
> 
> --{-- test code --
>   struct
> outer_arg0
> ;
>   struct
> inner_arg0
> ;
>   struct
> inner_arg1
> ;
> 
> //#define CLASS_SCOPE_SPECIALIZATION
>   template
>   < class OuterArg0
>   >
>   struct
> outer_tmpl
> {
>       template
>       < typename InnerArg0
>       , typename InnerArg1
>       >
>       struct
>     inner_tmpl
>   #ifndef CLASS_SCOPE_SPECIALIZATION
>     ;
>   #else
>     {};
>       template
>       < typename InnerArg0
>       >
>       struct
>     inner_tmpl
>       < InnerArg0
>       , inner_arg1
>       >
>     {
>             typedef
>           InnerArg0
>         inner_typdef
>         ;
>     };
>   #endif
> };
> 
> #ifndef CLASS_SCOPE_SPECIALIZATION
>   template
>   < //class OuterArg0
>   >
>       template
>       < typename InnerArg0
>       >
>       struct
> outer_tmpl
>   < outer_arg0
>   >::
>     inner_tmpl
>       < InnerArg0
>       , inner_arg1
>       >
>     {
>             typedef
>           InnerArg0
>         inner_typdef
>         ;
>     };
> #endif
> 
>     typedef
>   outer_tmpl<outer_arg0>
>   ::inner_tmpl
>   < inner_arg0
>   , inner_arg1
>   >
>   ::inner_typdef //error here.
> outer_inner_type
> ;
> --}-- test code --
[snip]
Just adding an outer_tmpl specialization solves the problem:

   template
   <// class OuterArg0
   >
   struct
outer_tmpl
   < outer_arg0
   >
{
       template
       < typename InnerArg0
       , typename InnerArg1
       >
       struct
     inner_tmpl
     ;
};



More information about the Gcc mailing list