Topic: implied template parameter types


Author: geoff.d.fortytwo@REMOVETHIS.intel.com (Geoff Fortytwo)
Date: 1998/11/02
Raw View
Valentin Bonnard <bonnardv@"pratique.fr"> writes:
>
> Geoff Fortytwo <geoff.d.fortytwo@REMOVETHIS.intel.com> writes:
>
> > How about this?:
>
> >   template<typename T<typename R> >
> >   struct N {
> >   };
>
> No, it's pointless.
>
> Write
>
> template <typename T>
>   struct N {
>   };

Here's an example of how such a thing could be useful (this uses a
templated function instead of a templated class, but the idea is the
same). I know STL iterators and containers aren't necessarily related
this way, but a user's iterator type could be. :

  template<typename IteratorType<typename ContainerType> >
  void F(IteratorType<ContainerType>& it)
  {
    ContainerType::value_type v;
    // ... put value in v
    it.push_back(v);
  }



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: geoff.d.fortytwo@REMOVETHIS.intel.com (Geoff Fortytwo)
Date: 1998/11/02
Raw View
The original reason why I asked this question about implied template
parameter types is that I wanted to be able to know the value_type of an
iterator. Apparently, the value_type typedef is only defined in the
containers, so I can't figure out a way to learn what the value_type is
when I'm given an iterator.

I have a template function that takes an iterator as an argument. I'd
like to return another iterator (well, to be precise, it's an iterator
adapter) that encapsulates the given iterator, but the new iterator type
is a template that requires the value_type of the items pointed to by the
iterator as well as the iterator type.

I don't want to force the user to specify the container type as an
argument because I don't have any need to know the container type except
to learn what the value_type is.



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1998/11/06
Raw View
Geoff Fortytwo wrote:

> The original reason why I asked this question about implied template
> parameter types is that I wanted to be able to know the value_type of an
> iterator. Apparently, the value_type typedef is only defined in the
> containers, so I can't figure out a way to learn what the value_type is
> when I'm given an iterator.

Use iterator_traits<Iterator>::value_type.



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos Reis <dosreis@DPTMaths.ENS-Cachan.Fr>
Date: 1998/11/06
Raw View
>>>>> Geoff Fortytwo <geoff.d.fortytwo@REMOVETHIS.intel.com>    crit :

> The original reason why I asked this question about implied template
> parameter types is that I wanted to be able to know the value_type of an
> iterator. Apparently, the value_type typedef is only defined in the
> containers, so I can't figure out a way to learn what the value_type is
> when I'm given an iterator.

Use iterator_traits<>

--
Gabriel Dos Reis                   |  Centre de Math   matiques et de
dosreis@cmla.ens-cachan.fr         |         Leurs Applications
Fax : (33) 01 47 40 21 69          |   ENS de Cachan -- CNRS (URA 1611)
               61, Avenue du Pdt Wilson, 94235 Cachan - Cedex
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos Reis <dosreis@DPTMaths.ENS-Cachan.Fr>
Date: 1998/11/06
Raw View
>>>>>    Geoff   , Geoff Fortytwo <geoff.d.fortytwo@REMOVETHIS.intel.com> wrote:

> Here's an example of how such a thing could be useful (this uses a
> templated function instead of a templated class, but the idea is the
> same). I know STL iterators and containers aren't necessarily related
> this way, but a user's iterator type could be. :

>   template<typename IteratorType<typename ContainerType> >
>   void F(IteratorType<ContainerType>& it)
>   {
>     ContainerType::value_type v;
     ^^
you need `typename' here.

>     // ... put value in v
>     it.push_back(v);
>   }

what about:

   template<template<class> class IteratorType, class ContainerType>
   void F(IteratorType<ContainerType>& it)
   {
       typename ContainerType::value_type v;
       // .. put value in v
       it.push_back(v);
   }

--
Gabriel Dos Reis
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: geoff.d.fortytwo@REMOVETHIS.intel.com (Geoff Fortytwo)
Date: 1998/10/30
Raw View
Is the following legal?:

  struct A {
    struct B {};
  };

  template<typename T>
  void F(T::B b)
  {
  }

  void main() {
    A::B b;
    // Can the compiler figure out
    // that F(b) means F<A>(b)
    F(b);
  }

How about this?:

  template<typename T>
  struct M {
  };

  template<typename T<typename R> >
  struct N {
  };

  void main() {
    N< M<int> > n;
  }

Or, how about this?:

  template<typename T>
  struct Q {
  };

  template<typename T>
  struct P {
    typedef Q<P> QP;
  };

  template<typename T, typename R>
  void G(T::R r)
  {
    // For this example, if it works, T==P, R==Q<P>
  }

  void main() {
    P::QP qp;
    G(qp);
  }
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@localhost.localdomain (Siemel Naran)
Date: 1998/11/02
Raw View
On 30 Oct 98 17:07:14 GMT, Geoff Fortytwo

Remember, the return type of main(...) is int, not void!  This is because
main(...) is a status function.  It's return value will be used by the
operating system.

-----

>  struct A {
>    struct B {};
>  };
>
>  template<typename T>
>  void F(T::B b)
>  {
>  }
>
>  void main() {
>    A::B b;
>    // Can the compiler figure out
>    // that F(b) means F<A>(b)
>    F(b);
>  }

I don't think the expression "T::B" where T is a template class and B
is a nested type of this template class is allowed.  Neither of my two
compilers accepts it (but this is not sufficient reason, of course).
Allowing it does make sense, although it would complicate life of the
compiler writers.  Given a declaration
     template <class T> void f(T::Nested);
the compiler has to store the argument of f(...) in its symbol table
not as any argument 'T' but as a nested class with concrete name
'Nested' as a member of some generic class 'T'.

This does work, but there is no deduction.

  struct A {
    struct B {};
  };

  template<typename T>
  void F(typename T::B b)
  {
  }

  int main() {
    A::B b;
    F<A>(b);
  }



Of course, one can always use traits.  This a less than perfect solution
because one can fool the compiler by putting the expected traits into
the wrong class.


  struct A {
    struct B { static const bool nested=true; };
  };

  template<typename T>
  void F(T b)
  {
       (void) T::nested;
  }

  int main() {
    F(A()); // error (fool compiler by giving class A the expected trait)
    F(A::B()); // ok
  }



A similar problem is to constrain the argument of a template to a
class derived from a certain base.  Eg,

class Fruit { };
class Apple  : public Fruit { };
class Orange : public Fruit { };

template <class Fruit> // Fruit should only be Apple or Orange
class Bag { ~Bag(); };

I don't think C++ has builtin mechanisms to ensure that this is the
case, although we can use static_cast to get the job done.

template <class SomeFruit>
Bag<SomeFruit>::~Bag()
{
     (void) static_cast<Fruit*>(static_cast<SomeFruit*>(0));
}
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]