Template function problem

S

syang8

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 said:
&,class Base<bool> const &)" (??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;
}
 
V

Victor Bazarov

syang8 said:
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

$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 T> class Base;
template said:
template<class T>
class Base
{
public:
friend ostream& operator << (ostream&, const Base&);

Replace with

friend ostream& operator said:
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
 
S

syang8

Yes. My bad. messed up simple things.

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.






Add here:

template<class T> class Base;
template<class T> ostream& operator << (ostream&, const Base<T>&);




Replace with

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










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 -
 

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
474,005
Messages
2,570,264
Members
46,859
Latest member
HeidiAtkin

Latest Threads

Top