Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > linker errors when I use template friends?

Reply
Thread Tools

linker errors when I use template friends?

 
 
John Harrison
Guest
Posts: n/a
 
      05-16-2004

"william xuuu" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
>
> Actually, I also got linker errors with template functions and template
> classes. And I avoided both of them successfully, by pouring foo.cpp
> into foo.h, according to the C++ FAQ.
>
> (http://www.parashift.com/c++-faq-lit...templates.html)
>
> And then, I pre-declared each template friend function above the
> definition of template class. But I still get template friends linker
> error. My compiler is gcc 3.3.3. Any hints? Thanks,
>


Probably your 'pre-declaration' is not the same as your actual definition.
So the linker tries to find the definiton for you pre-declaration and finds
nothing. Show us the code.

Don't #include foo.cpp in foo.h, that just makes things unnecessarily
complicated. Put everthing into foo.h and throw away foo.cpp. You know it
makes sense.

john


 
Reply With Quote
 
 
 
 
william xuuu
Guest
Posts: n/a
 
      05-16-2004

Actually, I also got linker errors with template functions and template
classes. And I avoided both of them successfully, by pouring foo.cpp
into foo.h, according to the C++ FAQ.

(http://www.parashift.com/c++-faq-lit...templates.html)

And then, I pre-declared each template friend function above the
definition of template class. But I still get template friends linker
error. My compiler is gcc 3.3.3. Any hints? Thanks,

--
William Xuuu
 
Reply With Quote
 
 
 
 
William Xuuu
Guest
Posts: n/a
 
      05-16-2004
"John Harrison" <(E-Mail Removed)> writes:

> Probably your 'pre-declaration' is not the same as your actual definition.
> So the linker tries to find the definiton for you pre-declaration and finds
> nothing. Show us the code.


Okay, here it is: (only two files)
//----------------------- "vector_set.h"

//pre declarations.
template <typename T> class Vector_Set;
template <typename T> Vector_Set<T> operator+ (const Vector_Set<T>& s1,
const Vector_Set<T>& s2);

//begin class itself
template <typename T> class Vector_Set
{
friend Vector_Set<T> operator+ (const Vector_Set<T>& s1, const
Vector_Set<T>& s2);
public:
...
};

// friends implementation
template <typename T> Vector_Set<T> operator+ (const Vector_Set<T>& s1,
const Vector_Set<T>& s2)
{
...
}

//----------------------- "vector_set_main.cpp"

typedef Vector_Set<int> Set;

Set a = Set(10), b = Set(10);
for(int i = 0; i < a.size(); i++)
if(i % 2 == 1)
a.add_member(i);
else
b.add_member(i);

// Here causes error!
a + b;



warnings and errors:

g++ -c vector_set_main.cpp
In file included from vector_set_main.cpp:8:
vector_set.h:29: warning: friend declaration `Vector_Set<T> operator+(const
Vector_Set<T>&, const Vector_Set<T>&)' declares a non-template function
g++ -g vector_set_main.o -O2 -lm -o vector_set_main
vector_set_main.o(.text+0x172): In function `main':
: undefined reference to `operator+(Vector_Set<int> const&, Vector_Set<int> const&)'

does this help?

--
William Xuuu
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      05-16-2004
> template <typename T> class Vector_Set
> {
> friend Vector_Set<T> operator+ (const Vector_Set<T>& s1, const
> Vector_Set<T>& s2);


This is a non-template function. It declares (as a friend) this function

Vector_Set<int> operator+ (const Vector_Set<int>& s1, const Vector_Set<int>&
s2);

>
> typedef Vector_Set<int> Set;
>
> Set a = Set(10), b = Set(10);
> for(int i = 0; i < a.size(); i++)
> if(i % 2 == 1)
> a.add_member(i);
> else
> b.add_member(i);
>
> // Here causes error!
> a + b;
>


Now the compiler thinks there are two functions to choose from, the
non-template (which you declared as a friend)

Vector_Set<int> operator+ (const Vector_Set<int>& s1, const Vector_Set<int>&
s2);

and the template (which you pre-declared)

template <class T>
Vector_Set<T> operator+ (const Vector_Set<T>& s1, const Vector_Set<T>& s2);

Given this choice the compiler always prefers the non-template. But since
you didn't define a non-template you get a link error.

The answer is to tell the compiler that the friend declaration refers to a
template function. You do that by adding '<T>' or '<>' after operator+.

template <typename T> class Vector_Set
{
friend Vector_Set<T> operator+ <>(const Vector_Set<T>& s1, const
Vector_Set<T>& s2);

It's easy to forget that you can have template and non-template versions of
the same function.

john


 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      05-16-2004
> The answer is to tell the compiler that the friend declaration refers to a
> template function. You do that by adding '<T>' or '<>' after operator+.
>


Hmm, seems gcc doesn't always handle the <T> form correctly. I would stick
with <>.

john


 
Reply With Quote
 
Greg Comeau
Guest
Posts: n/a
 
      05-16-2004
In article <(E-Mail Removed)>, William Xuuu <(E-Mail Removed)> wrote:
>"John Harrison" <(E-Mail Removed)> writes:
>> Probably your 'pre-declaration' is not the same as your actual definition.
>> So the linker tries to find the definiton for you pre-declaration and finds
>> nothing. Show us the code.

>
>Okay, here it is: (only two files)
>//----------------------- "vector_set.h"
>
>//pre declarations.
>template <typename T> class Vector_Set;
>template <typename T> Vector_Set<T> operator+ (const Vector_Set<T>& s1,
> const Vector_Set<T>& s2);
>
>//begin class itself
>template <typename T> class Vector_Set
>{
>friend Vector_Set<T> operator+ (const Vector_Set<T>& s1, const
> Vector_Set<T>& s2);
>public:
> ...
>};
>
>// friends implementation
>template <typename T> Vector_Set<T> operator+ (const Vector_Set<T>& s1,
> const Vector_Set<T>& s2)
>{
> ...
>}
>
>//----------------------- "vector_set_main.cpp"
>
> typedef Vector_Set<int> Set;
>
> Set a = Set(10), b = Set(10);
> for(int i = 0; i < a.size(); i++)
> if(i % 2 == 1)
> a.add_member(i);
> else
> b.add_member(i);
>
> // Here causes error!
> a + b;
>
>
>
>warnings and errors:
>
>g++ -c vector_set_main.cpp
>In file included from vector_set_main.cpp:8:
>vector_set.h:29: warning: friend declaration `Vector_Set<T> operator+(const
> Vector_Set<T>&, const Vector_Set<T>&)' declares a non-template function
>g++ -g vector_set_main.o -O2 -lm -o vector_set_main
>vector_set_main.o(.text+0x172): In function `main':
>: undefined reference to `operator+(Vector_Set<int> const&, Vector_Set<int> const&)'
>
>does this help?


Like John and your warning say: the decl is not the same
as the definition. Your fried declares a non-template op+ however
your definition is for a template one. Figure out which you
need and use the same for both.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
 
Reply With Quote
 
William Xuuu
Guest
Posts: n/a
 
      05-16-2004
"John Harrison" <(E-Mail Removed)> writes:

>> The answer is to tell the compiler that the friend declaration refers to a
>> template function. You do that by adding '<T>' or '<>' after operator+.
>>


Hmm, it works fine by adding <> or <T> as follows.

//begin class itself
template <typename T> class Vector_Set
{

friend Vector_Set<T> operator+<T> (const Vector_Set<T>& s1, const
Vector_Set<T>& s2);
};

While, the C++ FAQ didn't add <> or <T> ?!

Then I find it's not allowed to use + as:

a +<int> b;

So ?

> Hmm, seems gcc doesn't always handle the <T> form correctly. I would stick
> with <>.


Could you explain the differences between <T> and <> ?

And, i find that either adding <T> after pre-declaration or its
implementation, as:

//pre declarations.
template <typename T> class Vector_Set;
template <typename T> Vector_Set<T> operator+<T> (const Vector_Set<T>& s1,
const Vector_Set<T>& s2);


// friends implementation
template <typename T> Vector_Set<T> operator+<T> (const Vector_Set<T>& s1,
const Vector_Set<T>& s2)
{ ... }


both would cause same error:

error: partial specialization `operator+<T>' of function template

Why would it happen?

--
William Xuuu
 
Reply With Quote
 
Greg Comeau
Guest
Posts: n/a
 
      05-16-2004
In article <(E-Mail Removed)>, William Xuuu <(E-Mail Removed)> wrote:
>"John Harrison" <(E-Mail Removed)> writes:
>
>>> The answer is to tell the compiler that the friend declaration refers to a
>>> template function. You do that by adding '<T>' or '<>' after operator+.
>>>

>
>Hmm, it works fine by adding <> or <T> as follows.
>
>//begin class itself
>template <typename T> class Vector_Set
>{
>
>friend Vector_Set<T> operator+<T> (const Vector_Set<T>& s1, const
> Vector_Set<T>& s2);
>};
>
>While, the C++ FAQ didn't add <> or <T> ?!
>
>Then I find it's not allowed to use + as:
>
> a +<int> b;
>
>So ?


Not sure what you're asking, but perhaps you're looking for
the long-hand version like a.operator+<int>(b);

>
>> Hmm, seems gcc doesn't always handle the <T> form correctly. I would stick
>> with <>.

>
>Could you explain the differences between <T> and <> ?
>
>And, i find that either adding <T> after pre-declaration or its
>implementation, as:
>
>//pre declarations.
>template <typename T> class Vector_Set;
>template <typename T> Vector_Set<T> operator+<T> (const Vector_Set<T>& s1,
> const Vector_Set<T>& s2);
>
>
>// friends implementation
>template <typename T> Vector_Set<T> operator+<T> (const Vector_Set<T>& s1,
> const Vector_Set<T>& s2)
>{ ... }
>
>
>both would cause same error:
>
>error: partial specialization `operator+<T>' of function template
>
>Why would it happen?


Because a "primary" template declaration should not mention
it's arguments on its name, which the <T> would do above, but
since it's declared above, the friend is using it in your case,
not declaring it as such.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
 
Reply With Quote
 
William Xuuu
Guest
Posts: n/a
 
      05-17-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Greg Comeau) writes:

>>Hmm, it works fine by adding <> or <T> as follows.
>>
>>//begin class itself
>>template <typename T> class Vector_Set
>>{
>>
>>friend Vector_Set<T> operator+<T> (const Vector_Set<T>& s1, const
>> Vector_Set<T>& s2);
>>};
>>
>>While, the C++ FAQ didn't add <> or <T> ?!
>>
>>Then I find it's not allowed to use + as:
>>
>> a +<int> b;
>>
>>So ?

>
> Not sure what you're asking, but perhaps you're looking for
> the long-hand version like a.operator+<int>(b);
>


Right, a.operator+<int>(b), when we declare it to be a member of a
class. But here it's declared as a friend function! So don't we have to
specifly <T> as well? i.e, a +<int> b

--
William Xuuu
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      05-17-2004

"William Xuuu" <(E-Mail Removed)> wrote in message news:(E-Mail Removed)...
> "John Harrison" <(E-Mail Removed)> writes:
>
> >> The answer is to tell the compiler that the friend declaration refers

to a
> >> template function. You do that by adding '<T>' or '<>' after operator+.
> >>

>
> Hmm, it works fine by adding <> or <T> as follows.
>


The following code produces compiler errors on gcc.

#include <iostream>
using namespace std;

template <typename T> class Vector_Set;
template <typename T> Vector_Set<T> operator+ (const Vector_Set<T>& s1,
const Vector_Set<T>& s2);

template <typename T> class Vector_Set
{
friend Vector_Set<T> operator+ <T> (const Vector_Set<T>& s1, const
Vector_Set<T>& s2);
};

template <typename T> Vector_Set<T> operator+ (const Vector_Set<T>& s1,
const Vector_Set<T>& s2)
{
return s1;
}

int main()
{
typedef Vector_Set<int> Set;
Set a, b;
a + b;
}

Change <T> to <> in the friend declaration and it compiles, remove using
namespace std and it compiles. I think its a gcc bug.

john


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How to use the template member function of a template in the memberfunction of another template class? Peng Yu C++ 3 10-26-2008 03:51 PM
Linker errors on Template function definitions PyongHopscotch@gmail.com C++ 4 01-31-2006 06:52 AM
Errors, errors, errors Mark Goldin ASP .Net 2 01-17-2004 08:05 PM
linker errors: LNK2005 dullboy C++ 1 01-15-2004 09:04 AM
Linker Errors MiniDisc_2k2 C++ 2 07-05-2003 11:19 AM



Advertisments