Topic: Nested template class


Author: dbkruger@ix.netcom.com (Dov Kruger )
Date: 1996/07/01
Raw View
In <4r06qn$4am@erinews.ericsson.se> etmhuzw@ericsson.se (F. Hugo Zwaal)
writes:

>According to the DRAFT standard it is legal...
>By the way, if you use this kind of construction you will end
> up passing ints and chars etc. by reference, which is of course not
> the most efficient way to do it.
> Why don't you just let class A inherit from class iostream?

The reason for a templated class is to avoid the overhead of
polymorphism while retaining the generic capabilities.

I wish to write a wrapper, in this case, for an unknown class which
behaves like a stream, but which will not be an iostream.
The reason for the nested method:

template <class T> A& operator <<(const T& value)

is to avoid having to hard-code each type of print to this new stream,
built on top of the low-level stream.  Since it is inline code, this
construct would be highly efficient if it worked, in fact, far more
efficient than using virtual functions, whether passing by reference or
not.

In any case, when using inline functions, talking about the efficiency
of pass-by-reference is silly, since there will (presumably) be no
argument passing of any kind.

Adding class T as a parameter to the main class would not work:

template <class OutStr, class InStr, class T>
class InOutMgr {
private:
  OutStr& outStr_;
  InStr& inStr_;
public:
  ...
  InOutMgr& operator <<(const T& value) { outStr_ << value; }
};

main()
{
  InOutMgr<cout, cin, int> a; // a can only print integers!!!
  a << "abc"; // error!
}


What I am looking for is some implementation trick to make the
following work:

main()
{
    InOutMgr<cout, cin> a;
    a << "abc" << 5 << '\n';

    HighSpeedOutStream x("disk.buffer");
    HighSpeedInStream y("input.file");

    x << "abc" << 5 << '\n';

    InOutMgr<x, y> b;
    b << "abc" << 5 << '\n';
}

In other words, InOutMgr is a high-performance wrapper involving no
run-time overhead on unknown stream implementations, as long as the
streams support the normal operator << syntax.

I can, of course, hand-write the following operators:

InOutMgr& operator <<(int value) { outStr_ << value; return *this; }

InOutMgr& operator <<(double value);
InOutMgr& operator <<(char value);
InOutMgr& operator <<(char* value);

But I had hoped to avoid that since the code is the same each time.

Thanks to all of you who responded with the information that nested
template definitions are, in fact, legal.








[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: glenn@ims.uni-stuttgart.de (Glenn Carroll)
Date: 1996/07/03
Raw View
In article <4r8cqj$69s@dfw-ixnews4.ix.netcom.com>,
dbkruger@ix.netcom.com (Dov Kruger ) writes:

|> The reason for a templated class is to avoid the overhead of
|> polymorphism while retaining the generic capabilities.

I think this is a bad way to think about templates, but let's not get into
that.  If you want polymorphism *and* you want to avoid rewriting functions
which are the same for a variety of types, you can use both inheritance and
templates, so:

template< class InStr, class OutStr >
class InOutStr : public InStr, public OutStr {
...
};

If you don't want to expose the template parameter classes, use private
inheritance and publish the interface:

template< class InStr, class OutStr >
class InOutStr : private InStr, private OutStr {
public:
 IntStr::operator>>;
...
};

I have to admit that I know ordinary functions may be published in this
way, w/o specifying args or return value, but I haven't seen it done for
operators.  Someone care to say if it's legal?

This assumes that IntStr and OutStr have operator>> and operator<< defined
as members, not externally as global friend functions.  Ordinarily, it is
better to have the latter, as it permits conversion both sides of the
operator (either '<<' or '>>').

A last possibility is to use template functions:

template< class InStr, class OutStr, class Type >
istream&
operator>> ( InOutStr< InStr, OutStr >& istr, Type& rhs )
{
 return istr.instr() >> rhs;
}

Your trouble then is how to give such functions access to the streams.
The logical answer, declaring them as friends, brings us back to nested
template declarations . . .

Hope this helps

 glenn
8<==============================================
Glenn Carroll     glenn@ims.uni-stuttgart.de
Institut fuer Maschinelle Sprachverarbeitung
Azenbergstr. 12
70174 Stuttgart     (49)711-121-1387  office
Germany      (49)711-121-1366  fax
---
[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: dbkruger@ix.netcom.com (Dov Kruger )
Date: 1996/06/27
Raw View
Inside a template class, is it legal to have a templated method?
This code does not work on g++

template <class OutStr, class InStr>
class A {
  OutStr& outStr_;
  InStr&  inStr_;
public:
  template <class T> operator <<(const T& v) { outStr_ << v; }
};
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: etmhuzw@ericsson.se (F. Hugo Zwaal)
Date: 1996/06/28
Raw View
In article <4qucsr$kp5@sjx-ixn2.ix.netcom.com>, dbkruger@ix.netcom.com (Dov Kruger ) writes:
> Inside a template class, is it legal to have a templated method?
> This code does not work on g++
>
> template <class OutStr, class InStr>
> class A {
>   OutStr& outStr_;
>   InStr&  inStr_;
> public:
>   template <class T> operator <<(const T& v) { outStr_ << v; }
> };

According to the DRAFT standard it is legal... unfortunately there are not
many compilers that support it yet. The same accounts for your g++.

By the way, if you use this kind of construction you will end up passing ints
and chars etc. by reference, which is of course not the most efficient way to
do it. Wy don't you just let class A inherit form class iostream.

Groets, Hugo.




[ 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         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: vandevod@cs.rpi.edu (David Vandevoorde)
Date: 1996/06/28
Raw View
>>>>> "DK" == Dov Kruger <dbkruger@ix.netcom.com> writes:
DK> Inside a template class, is it legal to have a templated method?

Yes, but very few compilers support this yet.

 Daveed
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]