Linking Error unresolved external symbo when using template and friend

Y

Yoon-Soo Lee

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?
 
C

Chris \( Val \)

| 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
 
Y

Yoon-Soo Lee

Chris ( Val ) said:
| 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 said:
};

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.
 
C

Chris \( Val \)

|
| | >
| | > | 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
 
N

Nick Hounsome

Chris ( Val ) said:
|
| | >
| | > | 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 said:
| > | &,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.
 
C

Chris \( Val \)

[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
 

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
473,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top