Topic: friends of template classes


Author: Martin Sebor <marts@att.net>
Date: 1999/08/28
Raw View
Q) Given the following example (based on 14.5.3 Friends [temp.friend]),
how does one define the ordinary friend function foo outside of the body
of C? Note that foo (const C<T>&) is not a specialization of the
template function foo.


template <class T>
class C;

template <class T>
void foo (const C<T>&);

template <class T>
class C
{
   ...
   friend void foo<> (const C<T>&);

   // not related to the above
   friend void foo (const C<T>&);
   ...
};


[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: 1999/08/29
Raw View
On 28 Aug 1999 23:46:28 GMT, Martin Sebor <marts@att.net> wrote:

:
: Q) Given the following example (based on 14.5.3 Friends [temp.friend]),
: how does one define the ordinary friend function foo outside of the body
: of C?

As an ordinary function.  <g>

: Note that foo (const C<T>&) is not a specialization of the
: template function foo.
:
: template <class T>
: class C;
:
: template <class T>
: void foo (const C<T>&);
:
: template <class T>
: class C
: {
:    ...
:    friend void foo<> (const C<T>&);
:
:    // not related to the above
:    friend void foo (const C<T>&);
:    ...
: };

void foo (C<int> const&) { }
void foo (C<short> const&) { }
void foo (C<float> const&) { }
// etc.

John


[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/12/19
Raw View
In article <75bt6m$n65$1@bcarh8ab.ca.nortel.com>, Jim Cobban <Jim.Cobban
.jcobban@nortelnetworks.com> writes
>
>There is one place where the current C++ language definition practically
>forces the use of a friend definition.  That is in specifying how stream
>input and output are implemented for a class, because the extractor/inserter
>operators must be defined as functions outside the class in order to permit
>the left hand argument of the operator to be a stream.

not true.  There is a perfectly good idiom to do this:

class Myclass {
public:
      void printOn(ostream &) const;
// rest of class
};

inline ostream& operator<<(ostream & out, Myclass const & mc){
        mc.printOn(out);
        return out;
}

Indeed if you consistently call that member function printOn in all your
classes you can write:

template <typename T> ostream& operator<<(ostream& out), T const & t){
    t.printOn(out);
    return out;
};

BTW the basic idiom allows you to have a polymorphic operator<< if you
declare your printOn function virtual.



Francis Glassborow      Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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: Andrew Fitzgibbon <awf@robots.ox.ac.uk>
Date: 1998/12/16
Raw View

What is the meaning of the following code:


   template <class T>
   class Class {
     friend void f(T t) {
       .... do something ....
     }
   };

Do we end up with
a template class Class<T> and
an inline template function void f(T)?

Is it more correct to write

    template <class T>
    class Class {
      friend void f(T t);
    };

    template <class T>
    inline void f(T t) {
       .... do something ....
    }

Thanks in advance for any insights.

--
Andrew Fitzgibbon,                      awf@robots.ox.ac.uk
Robotics Research Group, University of Oxford                +44 01865 273127
     <a href=http://www.robots.ox.ac.uk/~awf> Home Page </a>
    "Never say there is no way"


[ 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: "Jim Cobban" <Jim.Cobban.jcobban@nortelnetworks.com>
Date: 1998/12/18
Raw View
In article <nzr9u0xjsj.fsf@volumnia.robots>,
Andrew Fitzgibbon  <awf@robots.ox.ac.uk> wrote:
>
>
>What is the meaning of the following code:
>
>
>   template <class T>
>   class Class {
>     friend void f(T t) {
>       .... do something ....
>     }
>   };
>
>Do we end up with
>a template class Class<T> and
>an inline template function void f(T)?

Since a friend function is NOT a member of the class, it does not make sense
to me that its definition should be contained inside the class definition.
Therefore I would have thought the preferred technique would be to have the
definition outside the template class definition as in your second example,
or even instantiated in a separate .cc file if you are prepared to
explicitly instantiate all required definitions, or if you have a compiler
which supports export.

There is one place where the current C++ language definition practically
forces the use of a friend definition.  That is in specifying how stream
input and output are implemented for a class, because the extractor/inserter
operators must be defined as functions outside the class in order to permit
the left hand argument of the operator to be a stream.  I have not been able
to figure out a way to get my compiler, g++ egcs-1.1b, to accept this
definition.  With option -Wall specified I get the following diagnostics:

EbcdicStr.h:149: warning: friend declaration `class ostream & operator
<<(class ostream &, const class EbcdicStr<size> &)'
EbcdicStr.h:149: warning:   declares a non-template function
EbcdicStr.h:149: warning:   (if this is not what you intended, make sure
EbcdicStr.h:149: warning:   the function template has already been declared,
EbcdicStr.h:149: warning:   and add <> after the function name here)

when I include the following definition of the output inserter for the
template class:

template<unsigned int size> class EbcdicStr
{
  ...
  friend ostream& operator <<(ostream& Stream,
         const EbcdicStr<size> & value);
  ...
};

template <unsigned int size>
ostream& operator <<(ostream& Stream,
       const EbcdicStr<size> & value)
{
  ...
}

The actual definition of the output inserter compiles and executes with no
problem, the only thing I cannot get to work is the friend specification, so
I have been forced to define a member function to the template class
EbcdicStr which operator << can use to get access to the information inside
the template class which the operator needs to format the output.  However
the existence of that member function, which is necessarily public, exposes
that information to the world.

So how do I declare the operator << to be a friend of the template class?
--
Jim Cobban   |  jcobban@nortel.ca                   |  Phone: (613) 763-8013
Nortel Networks (MED)                               |  FAX:   (613) 763-5199


[ 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              ]