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

Linking Error unresolved external symbo when using template and friend

P: n/a
I am using Visual C++ .NET 2003 and running into some linking error from the
following template code.
The error messages is
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 Test<int> &)"
(??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@ std@@AAV01@AAV?$Test@H@@@Z
) referenced in function _main
#include <iostream>
using namespace std;

template <class object>
class Test {
private:
object T;
public:
Test(object x): T(x) {};
friend ostream & operator << (ostream & out_stream, Test &test);

};

template <class object>
ostream & operator << (ostream & out_stream, Test<object> &test) {
out_stream << test.T ;
return out_stream;
}

cannot figure out what the problem is. Am I writing my template wrong or
what?
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"Yoon-Soo Lee" <yo****@vt.edu> wrote in message news:bt**********@solaris.cc.vt.edu...
| I am using Visual C++ .NET 2003 and running into some linking error from the
| following template code.
| The error messages is
| 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 Test<int> &)"
| (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@ std@@AAV01@AAV?$Test@H@@@Z
| ) referenced in function _main

[snip]

| cannot figure out what the problem is. Am I writing my template wrong or
| what?

Try this:

// Forward declarations...
template <class object>
class Test;

template <class object>
ostream & operator << (ostream & out_stream, Test<object> &test);

template <class object>
class Test {
private:
object T;
public:
Test(object x): T(x) {};
friend ostream & operator << <> (ostream & out_stream, Test<object> &test);

};

template <class object>
ostream & operator << (ostream & out_stream, Test<object> &test) {
out_stream << test.T ;
return out_stream;
}

Take note of the change to the friend prototype.

Cheers.
Chris Val
Jul 22 '05 #2

P: n/a

"Chris ( Val )" <ch******@bigpond.com.au> wrote in message
news:bt************@ID-110726.news.uni-berlin.de...

"Yoon-Soo Lee" <yo****@vt.edu> wrote in message news:bt**********@solaris.cc.vt.edu... | I am using Visual C++ .NET 2003 and running into some linking error from the | following template code.
| The error messages is
| 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 Test<int> &)"
| (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@ std@@AAV01@AAV?$Test@H@@@Z | ) referenced in function _main

[snip]

| cannot figure out what the problem is. Am I writing my template wrong or
| what?

Try this:

// Forward declarations...
template <class object>
class Test;

template <class object>
ostream & operator << (ostream & out_stream, Test<object> &test);

template <class object>
class Test {
private:
object T;
public:
Test(object x): T(x) {};
friend ostream & operator << <> (ostream & out_stream, Test<object> &test);
};

template <class object>
ostream & operator << (ostream & out_stream, Test<object> &test) {
out_stream << test.T ;
return out_stream;
}

Take note of the change to the friend prototype.

Cheers.
Chris Val


I figured out that forward declaration was unnecessary in my fragment of
code. Is it just a good programming habit? Also I would like to hear some
brief explanation why the prototype has to change in the way you have told
me to. Thank you.
Jul 22 '05 #3

P: n/a

"Yoon-Soo Lee" <yo****@vt.edu> wrote in message news:bt**********@solaris.cc.vt.edu...
|
| "Chris ( Val )" <ch******@bigpond.com.au> wrote in message
| news:bt************@ID-110726.news.uni-berlin.de...
| >
| > "Yoon-Soo Lee" <yo****@vt.edu> wrote in message
| news:bt**********@solaris.cc.vt.edu...
| > | I am using Visual C++ .NET 2003 and running into some linking error from
| the
| > | following template code.
| > | The error messages is
| > | 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 Test<int> &)"

[snip]

| I figured out that forward declaration was unnecessary in my fragment of
| code. Is it just a good programming habit?

Well, your right(you might not need the forward declarations), it is
just a workaround that I use for BCB5.

| Also I would like to hear some brief explanation why the prototype
| has to change in the way you have told me to. Thank you.

Ok, in your original friend declaration:
friend ostream & operator << (ostream & out_stream, Test &test);

....the ostream operator '<<' is declared as a 'NON-TEMPLATE' function.

Then you implement a 'template' version of operator '<<', expecting
it to be the implementation for the 'non-template' version:

template <class object>
ostream & operator << (ostream & out_stream, Test &test) {
out_stream << test.T ;
return out_stream;
}

The brackets '<>' in the friend declaration, tell the compiler
to use/instantiate the templated version of operator '<<', rather
than a new 'non-templated' one.

friend ostream & operator << <> (ostream & out_stream, Test<object> &test);

Where you could also do this:

friend ostream & operator << <object> (ostream & out_stream, Test<object> &test);
Now they are templated declarations - what you really wanted.

Cheers.
Chris Val
Jul 22 '05 #4

P: n/a

"Chris ( Val )" <ch******@bigpond.com.au> wrote in message
news:bt************@ID-110726.news.uni-berlin.de...

"Yoon-Soo Lee" <yo****@vt.edu> wrote in message news:bt**********@solaris.cc.vt.edu... |
| "Chris ( Val )" <ch******@bigpond.com.au> wrote in message
| news:bt************@ID-110726.news.uni-berlin.de...
| >
| > "Yoon-Soo Lee" <yo****@vt.edu> wrote in message
| news:bt**********@solaris.cc.vt.edu...
| > | I am using Visual C++ .NET 2003 and running into some linking error from | the
| > | following template code.
| > | The error messages is
| > | 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 Test<int> &)"

[snip]

| I figured out that forward declaration was unnecessary in my fragment of
| code. Is it just a good programming habit?

Well, your right(you might not need the forward declarations), it is
just a workaround that I use for BCB5.

| Also I would like to hear some brief explanation why the prototype
| has to change in the way you have told me to. Thank you.

Ok, in your original friend declaration:
friend ostream & operator << (ostream & out_stream, Test &test);

...the ostream operator '<<' is declared as a 'NON-TEMPLATE' function.

Then you implement a 'template' version of operator '<<', expecting
it to be the implementation for the 'non-template' version:

template <class object>
ostream & operator << (ostream & out_stream, Test &test) {
out_stream << test.T ;
return out_stream;
}

The brackets '<>' in the friend declaration, tell the compiler
to use/instantiate the templated version of operator '<<', rather
than a new 'non-templated' one.

friend ostream & operator << <> (ostream & out_stream, Test<object> &test);
Where you could also do this:

friend ostream & operator << <object> (ostream & out_stream, Test<object> &test);

Now they are templated declarations - what you really wanted.

Cheers.
Chris Val


A simpler approach for those of us who are antisocial and dislike friends is
simply to declare a member
ostream& print(ostream&) const;
And then define a non-friend template in terms of print.
Jul 22 '05 #5

P: n/a

"Nick Hounsome" <nh***@blueyonder.co.uk> wrote in message
news:BK*****************@news-binary.blueyonder.co.uk...

[snip]

| A simpler approach for those of us who are antisocial and dislike friends is
| simply to declare a member
| ostream& print(ostream&) const;
| And then define a non-friend template in terms of print.

Yes, that is an alternative, and often used in an inheritance
hierarchy with polymorphism, but my aim was to provide the OP
with a fix or solution to the problem code presented :-).

Cheers.
Chris Val
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.