Re: Problem overriding >> and << in a template class

From: Dietmar Kuehl (dietmar_kuehl_at_yahoo.com)
Date: 03/03/05


Date: 3 Mar 2005 05:25:54 -0800

franklini@hotmail.com wrote:
> hello people i. can anybody help me,

Interestingly, this looks very much like an article I recently rejected
from comp.lang.c++.moderated because it uses excessive code, i.e. it
includes loads of stuff entirely irrelevant to the question. Of course,
the rejection also mentioned the cause the of problem: The functions
you declare friends within the body of the class are non-template
functions and, except for the same name, entirely unrelated to the
function templates you use later!

For the friend functions to work correctly you need to declare them
*prior* to the class definition which in turn means that you also need
to forward declare the class definition itself. In addition, you need
to use a template argument list in the friend declaration. However,
since the template arguments can actually be deduced from the function
arguments, this template argument list can be empty. It just has to be
present to indicate that the function template is made a friend. The
whole code would look something like this:

  #include <iostream>

  template <typename> class foo;
  template <typename T>
  std::ostream& operator<< (std::ostream&, foo<T> const&);

  template <typename T>
  struct foo
  {
    foo(): val(17) {}
    // ...
    friend std::ostream& operator<< <>(std::ostream&, foo<T> const&);
  private:
    int val;
  };

  template<typename T>
  std::ostream& operator<< (std::ostream& os, foo<T> const& f)
  {
    return os << f.val;
  }

  int main()
  {
    std::cout << foo<int>() << "\n";
  }

BTW, this is not "overriding" the output operator but "overloading".
There is signification difference between these two terms although
they look very similar. Overriding is the term used to indicate that
a virtual function of a base class is, well, overridden by a derived
class, i.e. it is the mechanism used to implement dynamic polymorphism.
The overridden function has essentially the same signature as the
original on (although the return type may be covariant; theoretically
the arguments could be contravariant but this is not supported by C++).
Overloading on the other means that the same function name is used for
an otherwise unrelated function: the signatures of overloaded functions
vary be definition and there is no dynamic polymorphism involved. Of
course, the unrelated functions should to similar things when they
share a common name but this is technically not required.

--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting


Relevant Pages

  • Re: OK in Visual C++6.0 but not in Visual C++ .NET 2003?
    ... The example you showed declared function template to be a friend of a class ... class MyClass ... This would result in InitClass being a friend of MyClassin cases where T ... You have to declare your friend a little differently ...
    (microsoft.public.dotnet.languages.vc)
  • Re: template -> instance -> function unresolved ???
    ... friend template function accessing private data in the template. ... i compile this into a dll (yes i know, there is no exported function from ... have to declare the function before the class who's friend it is supposed ...
    (microsoft.public.vc.language)
  • Re: Circular Class Template Friendship
    ... > My issue is the syntax of declaring a friend class within ... > which the string is a fixed width that is specialized. ... it is still possible to have Name_Id_Table template ... the friend class declaration. ...
    (comp.lang.cpp)
  • Re: Class templates and friend function templates
    ... > It never occurred to me that the friend declaration could be an overload. ... > template ... I suspect the online version uses an EDG option to "instantiate ...
    (microsoft.public.vc.language)
  • Re: Template friendship to nested template class
    ... friend struct INNER; ... Probably you are missing an EXTRA template to declare ... I think it's because the name referred to in a 'friend' declaration is looked up to exist at the namespace scope. ...
    (microsoft.public.vc.language)