Topic: Dependent (nested) types as template function args


Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Wed, 7 Nov 2001 22:36:35 GMT
Raw View
Ren=E9 van Oostrum <rene+gnus@cs.uu.nl> writes:

| I'm having troubles with using nested types of template classes as
| arguments of template functions. Consider the following code:
|=20
|   template< typename T > struct C {
|     struct nested {};
|   };
|=20
|   template< typename T >
|   void f( typename C<T>::nested n ){ }

Here, the template-parameter T appears in a non-deducible context so
the template-argument process will fail.

--=20
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Ren van Oostrum <rene+gnus@cs.uu.nl>
Date: Thu, 1 Nov 2001 15:19:43 GMT
Raw View
I'm having troubles with using nested types of template classes as
arguments of template functions. Consider the following code:

  template< typename T > struct C {
    struct nested {};
  };

  template< typename T >
  void f( typename C<T>::nested n ){ }

  int main(){
    f( C<int>::nested() );      // 1: no matching funtion
    f<int>( C<int>::nested() ); // 2: OK

    return 0;
  }

I was hoping that the template arguments of function f would be
automatically deduced for the call in the line annotated with `1'.
However, both g++ 3.0 and Comeau online reject this line, telling me
that no matching function is found.

The line annotated with `2' is accepted by both compilers. However,
the code that led to this posting, f is actually operator<<, and it is
rather awkward to explicitly specify the template argument in that
case.

I tried to get away with line 1 by adding an explicit template
function instantiation just before main:

  template void f<int>( C<int>::nested );

Alas, line 1 was still rejected by both compilers.

My questions:

1) Are the compilers right in rejecting line 1, both with and without
   the explicit instantiation of f<int> present?

2) If they are, is there any other way of attaining what I want, i.e.,
   automatic template argument deduction where the function argument
   is a nested type?

Thanks,
Ren

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]





Author: Hyman Rosen <hyrosen@mail.com>
Date: Fri, 2 Nov 2001 08:01:45 GMT
Raw View
Ren=E9 van Oostrum wrote:

>   template< typename T > struct C { struct nested {}; };
>   template< typename T > void f( typename C<T>::nested n ){ }
>   int main(){
>     f( C<int>::nested() );      // 1: no matching funtion
>     f<int>( C<int>::nested() ); // 2: OK
>   }
>=20
> 1) Are the compilers right in rejecting line 1, both with and without
>    the explicit instantiation of f<int> present?


Yes. Here's a rationale for why this must be so:

 template<> struct C<double> { typedef C<int>::nested nested; };
 f( C<double>::nested() );

See? Should it call f<int> or f<double>?


> 2) If they are, is there any other way of attaining what I want, i.e.,
>    automatic template argument deduction where the function argument
>    is a nested type?


Not of the type in which the nested type was defined. You could stick a
typedef of the outer type inside the nested type, and just call explicitl=
y:

 template< typename T > struct C { struct nested { typedef T t; }; };
 template< typename T > void f( typename C<T>::nested n ) { }
 template< typename T > void g( T n ) { f<typename T::t>(n); }
 g( C<int>::nested() );

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]