Problem with operator << and templates

D

Darío Griffo

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
 
K

kwikius

Darío Griffo said:
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
 
D

Darío Griffo

#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
 
K

kwikius

#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
 
J

James Kanze

#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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top