Connecting Tech Pros Worldwide Forums | Help | Site Map

Template function problem

syang8
Guest
 
Posts: n/a
#1: Jun 22 '07
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>
Quote:
&,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;
}


Victor Bazarov
Guest
 
Posts: n/a
#2: Jun 22 '07

re: Template function problem


syang8 wrote:
Quote:
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>
Quote:
>&,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.
Quote:
>
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>&);
Quote:
>
template<class T>
class Base
{
public:
friend ostream& operator << (ostream&, const Base&);
Replace with

friend ostream& operator << <T(ostream&, const Base&);
Quote:
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


syang8
Guest
 
Posts: n/a
#3: Jun 22 '07

re: Template function problem


Yes. My bad. messed up simple things.

On Jun 22, 4:58 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Quote:
syang8 wrote:
Quote:
I am trying to design classes with stream support. Basically, I want
the operator << work for the base class and all the derived classes.
>
Quote:
If the base class is a template class, and the operator << is also
designed as a template function. The program has following linking
errors:
>
Quote:
"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>
Quote:
&,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.
>
>
>
Quote:
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.
>
Quote:
Here are the example codes:
---------------------------------------------------------------------------*-------------------------------------------------------------------------
#include <iostream>
#include <string>
>
Quote:
using namespace std;
>
Add here:
>
template<class Tclass Base;
template<class Tostream& operator << (ostream&, const Base<T>&);
>
>
>
Quote:
template<class T>
class Base
{
public:
friend ostream& operator << (ostream&, const Base&);
>
Replace with
>
friend ostream& operator << <T(ostream&, const Base&);
>
>
>
>
>
Quote:
virtual string get_buffer() const {return "Base class";}
};
>
Quote:
class Derived : public Base<bool>
{
public:
virtual string get_buffer() const {return "Derived class";}
};
>
Quote:
template<class T>
ostream& operator << (ostream& os, const Base<T>& a)
{
os << a.get_buffer();
return os;
}
>
Quote:
/*
template<>
ostream& operator << (ostream& os, const Base<bool>& a)
*/
>
Quote:
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 -

Closed Thread