Problem with operator << and templates

Discussion in 'C++' started by Darío Griffo, Aug 2, 2008.

  1. I'm having an error with this code

    #include <iostream>

    template < typename T> class TestOpTemplate
    {
    public:
    friend std::eek:stream& operator<< <>(std::eek:stream& os, const
    TestOpTemplate<T>& m);
    };

    The error is
    declaration of 'operator<<' as non-function

    Searchin on the web, i've found that it could be solved using
    parenthesis aroung the funcion name, but it doesn't

    friend std::eek:stream& :):eek:perator<< <> ) (std::eek:stream& os, const
    TestOpTemplate<T>& m);

    still doesn't work
    Any help please
     
    Darío Griffo, Aug 2, 2008
    #1
    1. Advertising

  2. Darío Griffo

    kwikius Guest

    "Darío Griffo" <> wrote in message
    news:...
    > I'm having an error with this code
    >
    > #include <iostream>
    >
    > template < typename T> class TestOpTemplate
    > {
    > public:
    > friend std::eek:stream& operator<< <>(std::eek:stream& os, const
    > TestOpTemplate<T>& m);
    > };


    #include <iostream>

    template < typename T> class TestOpTemplate
    {
    public:
    friend std::eek:stream& operator<<(std::eek:stream& os, const
    TestOpTemplate<T>& m);
    };

    regards
    Andy Little
     
    kwikius, Aug 2, 2008
    #2
    1. Advertising

  3. On Aug 2, 5:04 pm, "kwikius" <> wrote:
    > #include <iostream>
    >
    > template < typename T> class TestOpTemplate
    > {
    > public:
    > friend std::eek:stream& operator<<(std::eek:stream& os, const
    > TestOpTemplate<T>& m);
    >
    > };
    >
    > regards
    > Andy Little


    But when I implement the function:

    template < typename T> std::eek:stream& operator<<(std::eek:stream& os,
    const TestOpTemplate<T>& m)
    {
    return os
    }


    i get this

    test.cpp:6: warning: friend declaration 'std::eek:stream&
    operator<<(std::eek:stream&, const TestOpTemplate<T>&)' declares a non-
    template function
    test.cpp:6: note: (if this is not what you intended, make sure the
    function template has already been declared and add <> after the
    function name here)
    linking test (libtool)

    That's why i've putted <> after the name. Compiling with g++ 4.3.1
     
    Darío Griffo, Aug 2, 2008
    #3
  4. Darío Griffo

    kwikius Guest

    "Darío Griffo" <> wrote in message
    news:...
    On Aug 2, 5:04 pm, "kwikius" <> wrote:
    > #include <iostream>
    >
    > template < typename T> class TestOpTemplate
    > {
    > public:
    > friend std::eek:stream& operator<<(std::eek:stream& os, const
    > TestOpTemplate<T>& m);
    >
    > };
    >
    > regards
    > Andy Little


    But when I implement the function:

    template < typename T> std::eek:stream& operator<<(std::eek:stream& os,
    const TestOpTemplate<T>& m)
    {
    return os
    }


    i get this

    test.cpp:6: warning: friend declaration 'std::eek:stream&
    operator<<(std::eek:stream&, const TestOpTemplate<T>&)' declares a non-
    template function
    test.cpp:6: note: (if this is not what you intended, make sure the
    function template has already been declared and add <> after the
    function name here)
    linking test (libtool)

    That's why i've putted <> after the name. Compiling with g++ 4.3.1



    hmmm... Dunno I guess you will have to wait for the experts ... Meanwhile
    you could try just defining the function in the class maybe...

    regards
    Andy Little
     
    kwikius, Aug 2, 2008
    #4
  5. Darío Griffo

    James Kanze Guest

    On Aug 2, 10:04 pm, "kwikius" <> wrote:
    > "Darío Griffo" <> wrote in message


    > news:...


    > > I'm having an error with this code


    > > #include <iostream>


    > > template < typename T> class TestOpTemplate
    > > {
    > > public:
    > > friend std::eek:stream& operator<< <>(std::eek:stream& os, const
    > > TestOpTemplate<T>& m);
    > > };


    > #include <iostream>


    > template < typename T> class TestOpTemplate
    > {
    > public:
    > friend std::eek:stream& operator<<(std::eek:stream& os, const
    > TestOpTemplate<T>& m);
    > };


    Be careful. That declares a non-template function as friend, so
    he'll have to implement a non-template function for every
    instance of TestOpTemplate.

    I know that the current draft very explicitly provides for three
    alternatives with regards to friend: a non-template, a template
    for which only the corresponding specialization is a friend, and
    a template for which all specializations are friend. For some
    reason, however, I think that this is a recent clarification or
    fix, and the compilers vary in what they actually implement
    (except that all support a non-template as friend in more or
    less the same manner). Anyway, my "standard" solution is to
    define a public member function print(), and then define the
    operator<< inline, which just calls it, e.g.:

    template< typename T >
    class TestOpTemplate
    {
    public:
    void print( std::eek:stream& ) ;
    friend std::eek:stream& operator<<(
    std::eek:stream& dest,
    TestOpTemplate< T > const& obj )
    {
    obj.print( dest ) ;
    return dest ;
    }
    } ;

    Since the friend function is defined each time the template is
    specialized, it doesn't matter that it's not a template; you get
    a new non-template function for each type.

    Of course, in practice, the case comes up fairly often, so I've
    moved these functions down into a templated base class, so it's
    sufficient that my class derives from it, e.g.:

    template< typename T >
    struct IOStreamOperators
    {
    friend std::eek:stream& operator<<(
    std::eek:stream& dest,
    T const& obj )
    {
    obj.print( dest ) ;
    return dest ;
    }
    friend std::istream& operator>>(
    std::istream& source,
    T& obj )
    {
    obj.scan( source ) ;
    return source ;
    }
    } ;

    template< typename T >
    class TestOpTemplate
    : public IOStreamOperators< TestOpTemplate < T > >
    {
    public:
    void print( std::eek:stream& ) ;
    } ;

    And in case it isn't obvious:

    -- the only reason for the friend in these cases is to allow
    you to define the non-member function in the class
    definition, and

    -- if you never used one of the functions in IOStreamOperators,
    it won't be instantiated, so you won't get an error if the
    member function it calls isn't present.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Aug 2, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. JKop
    Replies:
    3
    Views:
    492
  2. Generic Usenet Account
    Replies:
    3
    Views:
    841
    Generic Usenet Account
    Jul 14, 2005
  3. BigMan
    Replies:
    1
    Views:
    443
  4. recover
    Replies:
    2
    Views:
    834
    recover
    Jul 25, 2006
  5. saxman
    Replies:
    2
    Views:
    441
    saxman
    Jun 12, 2007
Loading...

Share This Page