How to define inserter or extractor for a class template

L

laikon

this question is about how to define friend functions for a class
template.
the following is an example.

template <typename T>
class Array
{
private:
T* parr;
int sz;

friend ostream& operator << (ostream& os, const Array<T>& rhs);
};

template <class T>
ostream& operator << (ostream& os, const Array<T>& rhs)
{
for (int i = 0; i < rhs.sz; ++i)
os << rhs.parr << "\t";
return os;
}

these codes work well in VC++ 6.0, while linking errors are given in VC
++ 2005.
 
B

Barry

this question is about how to define friend functions for a class
template.
the following is an example.

template <typename T>
class Array
{
private:
        T* parr;
        int sz;

        friend ostream& operator << (ostream& os, const Array<T>& rhs);

friend ostream& operator said:
};

template <class T>
ostream& operator << (ostream& os, const Array<T>& rhs)
{
        for (int i = 0; i < rhs.sz; ++i)
                os << rhs.parr << "\t";
        return os;

}

these codes work well in VC++ 6.0, while linking errors are given in VC
++ 2005.
 
B

Barry

friend ostream& operator<< <T> (ostream& os, const Array<T>& rhs);

Note that this is only a work around for VC2005.
According to 10.5.3
We should forward declaring "template operator<<", which requires
forward
declaration of "template class Array".
So the code looks like this:

template <typename T>
class Array;

template <typename T>
ostream& operator<< (ostream&, Array<T> const&);

template <typename T>
class Array {
...

friend
ostream& operator<< <T> (ostream&, Array const&); // Array<T> is
also fine
};

template <typename T>
ostream& operator<< (ostream& ostrm, Array<T> const& a) {
...
}
template <class T>
ostream& operator << (ostream& os, const Array<T>& rhs)
{
        for (int i = 0; i < rhs.sz; ++i)
                os << rhs.parr << "\t";
        return os;

these codes work well in VC++ 6.0, while linking errors are given in VC
++ 2005.

 
J

James Kanze

this question is about how to define friend functions for a
class template.

It's difficult:).
the following is an example.
template <typename T>
class Array
{
private:
T* parr;
int sz;
friend ostream& operator << (ostream& os, const Array<T>& rhs);

Note that this declares a non-template operator<< as a friend.
That's probably not what you want.
template <class T>
ostream& operator << (ostream& os, const Array<T>& rhs)
{
for (int i = 0; i < rhs.sz; ++i)
os << rhs.parr << "\t";
return os;
}

these codes work well in VC++ 6.0, while linking errors are
given in VC ++ 2005.

If you have a declaration of the operator<<, as a template,
before you define the class, I think it should work. In
practice, I've found it more convenient to only use inline
friends, so the problem doesn't come up. Something like:

template< typename T >
class Array
{
// ...
public:
void print( std::eek:stream& dest ) const ;
friend std::eek:stream&
operator<<( std::eek:stream& dest,
Array< T > const& array )
{
array.print( dest ) ;
return *this ;
}
} ;

The friend may be a non-template function, but it doesn't
matter, since I don't have to declare it anywhere else.
 

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,774
Messages
2,569,599
Members
45,167
Latest member
SusanaSwan
Top