By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,156 Members | 1,047 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,156 IT Pros & Developers. It's quick & easy.

Template function problem

P: n/a
Dear all,

I am trying to design classes with stream support. Basically, I want
the operator << work for the base class and all the derived classes.

If the base class is a template class, and the operator << is also
designed as a template function. The program has following linking
errors:

"error LNK2019: unresolved external symbol "class
std::basic_ostream<char,struct std::char_traits<char & __cdecl
operator<<(class std::basic_ostream<char,struct std::char_traits<char>
&,class Base<boolconst &)" (??6@YAAAV?$basic_ostream@DU?
$char_traits@D@std@@@std@@AAV01@ABV?$Base@_N@@@Z) referenced in
function _main"

However, if the base class is not a template class. Everything is ok
and the link error dosen't exist. Note that I tried instantiate the
operator << explicitly. But it doesn't solve the problem.

Here are the example codes:
----------------------------------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <string>

using namespace std;

template<class T>
class Base
{
public:
friend ostream& operator << (ostream&, const Base&);
virtual string get_buffer() const {return "Base class";}
};

class Derived : public Base<bool>
{
public:
virtual string get_buffer() const {return "Derived class";}
};

template<class T>
ostream& operator << (ostream& os, const Base<T>& a)
{
os << a.get_buffer();
return os;
}

/*
template<>
ostream& operator << (ostream& os, const Base<bool>& a)
*/

int main()
{
Derived b;
cout << b << endl;
}

Jun 22 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
syang8 wrote:
I am trying to design classes with stream support. Basically, I want
the operator << work for the base class and all the derived classes.

If the base class is a template class, and the operator << is also
designed as a template function. The program has following linking
errors:

"error LNK2019: unresolved external symbol "class
std::basic_ostream<char,struct std::char_traits<char & __cdecl
operator<<(class std::basic_ostream<char,struct std::char_traits<char>
>&,class Base<boolconst &)" (??6@YAAAV?$basic_ostream@DU?
$char_traits@D@std@@@std@@AAV01@ABV?$Base@_N@@@Z) referenced in
function _main"
The friend declaration in your code instroduces a non-template function
into the namespace, which the compiler picks (and wants to call), and
that's what the linker is missing. If you replace it with a declaration
of a _template_, it will have a need to instantiate your op<< template.

Make sure that when declaring a function for the first time in a friend
declaration, you don't declare it wrongly.
>
However, if the base class is not a template class. Everything is ok
and the link error dosen't exist. Note that I tried instantiate the
operator << explicitly. But it doesn't solve the problem.

Here are the example codes:
----------------------------------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <string>

using namespace std;
Add here:

template<class Tclass Base;
template<class Tostream& operator << (ostream&, const Base<T>&);
>
template<class T>
class Base
{
public:
friend ostream& operator << (ostream&, const Base&);
Replace with

friend ostream& operator << <T(ostream&, const Base&);
virtual string get_buffer() const {return "Base class";}
};

class Derived : public Base<bool>
{
public:
virtual string get_buffer() const {return "Derived class";}
};

template<class T>
ostream& operator << (ostream& os, const Base<T>& a)
{
os << a.get_buffer();
return os;
}

/*
template<>
ostream& operator << (ostream& os, const Base<bool>& a)
*/

int main()
{
Derived b;
cout << b << endl;
}
It should now compile.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 22 '07 #2

P: n/a
Yes. My bad. messed up simple things.

On Jun 22, 4:58 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
syang8 wrote:
I am trying to design classes with stream support. Basically, I want
the operator << work for the base class and all the derived classes.
If the base class is a template class, and the operator << is also
designed as a template function. The program has following linking
errors:
"error LNK2019: unresolved external symbol "class
std::basic_ostream<char,struct std::char_traits<char & __cdecl
operator<<(class std::basic_ostream<char,struct std::char_traits<char>
&,class Base<boolconst &)" (??6@YAAAV?$basic_ostream@DU?
$char_traits@D@std@@@std@@AAV01@ABV?$Base@_N@@@Z) referenced in
function _main"

The friend declaration in your code instroduces a non-template function
into the namespace, which the compiler picks (and wants to call), and
that's what the linker is missing. If you replace it with a declaration
of a _template_, it will have a need to instantiate your op<< template.

Make sure that when declaring a function for the first time in a friend
declaration, you don't declare it wrongly.
However, if the base class is not a template class. Everything is ok
and the link error dosen't exist. Note that I tried instantiate the
operator << explicitly. But it doesn't solve the problem.
Here are the example codes:
---------------------------------------------------------------------------*-------------------------------------------------------------------------
#include <iostream>
#include <string>
using namespace std;

Add here:

template<class Tclass Base;
template<class Tostream& operator << (ostream&, const Base<T>&);
template<class T>
class Base
{
public:
friend ostream& operator << (ostream&, const Base&);

Replace with

friend ostream& operator << <T(ostream&, const Base&);


virtual string get_buffer() const {return "Base class";}
};
class Derived : public Base<bool>
{
public:
virtual string get_buffer() const {return "Derived class";}
};
template<class T>
ostream& operator << (ostream& os, const Base<T>& a)
{
os << a.get_buffer();
return os;
}
/*
template<>
ostream& operator << (ostream& os, const Base<bool>& a)
*/
int main()
{
Derived b;
cout << b << endl;
}

It should now compile.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask- Hide quoted text -

- Show quoted text -

Jun 22 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.