Template Friend

P

paidojoao-groups

Given this code:


#include <iostream>
#include <string>

class timestamp
{
public:
timestamp() {
std::cout << "--> default constructor" << std::endl;
}

template <class charT, class traits>
friend
std::basic_ostream<charT, traits>&
operator<< (std::basic_ostream<charT, traits>& strm, const timestamp& ts);

private:
// implementation not relevant
};

template<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& strm, const timestamp& ts)
{
using namespace std;

strm << "--> operator<<()";

return strm;
}

int main()
{
timestamp p;
std::cout << p << std::endl; // line 36
return 0;
}

-------------------------------------------

VC 7.1 (13.10.3077) complains with

bug.cpp(36) : error C2563: mismatch in formal parameter list
bug.cpp(36) : error C2568: '<<' : unable to resolve function overload

Borland C++ 5.6.4 and G++ 3.2 compile without errors.

Who is wrong and who is right?

Changing to

friend
std::eek:stream&
operator<< (std::eek:stream& strm, const timestamp& ts);

and the compiler stops complaining.

Josue Gomes
josuegomes at yahoo dot com
 
R

Rob Williscroft

(e-mail address removed) wrote in @posting.google.com in comp.lang.c++:
template<class charT, class traits>
std::basic_ostream<charT, traits>&
operator<<(std::basic_ostream<charT, traits>& strm,
const timestamp& ts)
{
using namespace std;

strm << "--> operator<<()";

return strm;
}

int main()
{
timestamp p;
std::cout << p << std::endl; // line 36
return 0;
}

-------------------------------------------

VC 7.1 (13.10.3077) complains with

bug.cpp(36) : error C2563: mismatch in formal parameter list
bug.cpp(36) : error C2568: '<<' : unable to resolve function overload

Borland C++ 5.6.4 and G++ 3.2 compile without errors.

Who is wrong and who is right?

VC7.1 is wrong you've found a bug.
Changing to

friend
std::eek:stream&
operator<< (std::eek:stream& strm, const timestamp& ts);

and the compiler stops complaining.

Yes, but this isn't the same function as your template function
above, simply removing the friend declaration also works-around
the bug.

Workaround: define the friend inline in the class, if its implementation
is unsutible for inlining have it forward to a non-inline template member
instead.


#include <iostream>
#include <ostream>

class timestamp
{
template < typename charT, typename traits>
friend std::basic_ostream<charT, traits>& operator<< (
std::basic_ostream<charT, traits>& strm, timestamp const& ts
)
{
return ts.m_print( strm );
}

private:

template < typename charT, typename traits>
std::basic_ostream<charT, traits>&
m_print( std::basic_ostream<charT, traits>& ) const;

};

template < typename charT, typename traits>
std::basic_ostream<charT, traits>&
timestamp::m_print( std::basic_ostream<charT, traits>& strm) const
{
strm << "--> operator<<()";

return strm;
}

int main()
{
timestamp p;
std::cout << p << std::endl;
}

Unfortunatly this doesn't work for Borland C++ 5.6.4, so your
left with making m_print() public and just delaring/defining
operator << () at namespace scope and forwarding to m_print.

Rob.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top