Connecting Tech Pros Worldwide Help | Site Map

Template Friend Function, GCC and C++ FAQ Lite

Christophe Barbe
Guest
 
Posts: n/a
#1: Jul 19 '05
I posted a few days ago about the same problem but was not very clear. So
here is my second take at it.

Basically with GCC 3.3.2, I can't compile the example [34.15] from the
C++ FAQ Lite available online at
http://www.parashift.com/c++-faq-lit...html#faq-34.15

Below are the two files that I compile with
g++ foo.cpp -o foo
or
g++ -DMAKE_GCC_HAPPY foo.cpp -o foo

Gcc is happy when I use -DMAKE_GCC_HAPPY but if I don't it says:

$ g++ foo.cpp -o foo
In file included from foo.cpp:1:
foo.h:17: warning: friend declaration `Foo<T> operator+(const Foo<T>&, const
Foo<T>&)' declares a non-template function
foo.h:17: warning: (if this is not what you intended, make sure the function
template has already been declared and add <> after the function name here)
-Wno-non-template-friend disables this warning
foo.h:18: warning: friend declaration `std::ostream& operator<<(std::ostream&,
const Foo<T>&)' declares a non-template function
/tmp/ccYOJ2nR.o(.text+0x5c): In function `main':
: undefined reference to `operator+(Foo<int> const&, Foo<int> const&)'
/tmp/ccYOJ2nR.o(.text+0x70): In function `main':
: undefined reference to `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Foo<int> const&)'
collect2: ld returned 1 exit status

My understanding is that defining the friend functions before the class is
not enough to make obvious to the compiler that they are template
functions.

Any ideas?

Thanks,
Christophe

---- foo.cpp ----
#include "foo.h"
#include <string>
#include <iostream>

using namespace std;

int main()
{
Foo<int> lhs(1);
Foo<int> rhs(2);
Foo<int> result = lhs + rhs;
cout << result << endl;
}
---- end of foo.cpp ----

---- foo.h ----
#include <iostream>

#ifdef MAKE_GCC_HAPPY
#define __TFS__ <>
#else
#define __TFS__
#endif

template<typename T> class Foo; // pre-declare the template class itself
template<typename T> Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs);
template<typename T> std::ostream& operator<< (std::ostream& o, const Foo<T>& x);

template<typename T>
class Foo {
public:
Foo(const T& value = T());
friend Foo<T> operator+ __TFS__ (const Foo<T>& lhs, const Foo<T>& rhs);
friend std::ostream& operator<< __TFS__ (std::ostream& o, const Foo<T>& x);
private:
T value_;
};

template<typename T>
Foo<T>::Foo(const T& value) : value_(value)
{ }

template<typename T>
Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs)
{
return Foo<T>(lhs.value_ + rhs.value_);
}

template<typename T>
std::ostream& operator<< (std::ostream& o, const Foo<T>& x)
{
return o << x.value_;
}


---- end of foo.h ----
Rolf Magnus
Guest
 
Posts: n/a
#2: Jul 19 '05

re: Template Friend Function, GCC and C++ FAQ Lite


Christophe Barbe wrote:
[color=blue]
> I posted a few days ago about the same problem but was not very clear.
> So here is my second take at it.
>
> Basically with GCC 3.3.2, I can't compile the example [34.15] from the
> C++ FAQ Lite available online at
> http://www.parashift.com/c++-faq-lite[/color]
containers-and-templates.html#faq-34.15[color=blue]
>
> Below are the two files that I compile with
> g++ foo.cpp -o foo
> or
> g++ -DMAKE_GCC_HAPPY foo.cpp -o foo
>
> Gcc is happy when I use -DMAKE_GCC_HAPPY but if I don't it says:
>
> $ g++ foo.cpp -o foo
> In file included from foo.cpp:1:
> foo.h:17: warning: friend declaration `Foo<T> operator+(const Foo<T>&,
> const
> Foo<T>&)' declares a non-template function
> foo.h:17: warning: (if this is not what you intended, make sure the
> function
> template has already been declared and add <> after the function
> name here) -Wno-non-template-friend disables this warning
> foo.h:18: warning: friend declaration `std::ostream&
> operator<<(std::ostream&,
> const Foo<T>&)' declares a non-template function
> /tmp/ccYOJ2nR.o(.text+0x5c): In function `main':
> : undefined reference to `operator+(Foo<int> const&, Foo<int> const&)'
> /tmp/ccYOJ2nR.o(.text+0x70): In function `main':
> : undefined reference to `operator<<(std::basic_ostream<char,
> : std::char_traits<char> >&, Foo<int> const&)'
> collect2: ld returned 1 exit status
>
> My understanding is that defining the friend functions before the
> class is not enough to make obvious to the compiler that they are
> template functions.
>
> Any ideas?[/color]

gcc is right. In chapter C.13.2 of TC++PL3, Stroustrup writes an
example:


========================= begin quote ================================

template<class T> class Matrix;

template<class T> class Vector {
T v[4];
public:
friend Vector operator*<>(const Matrix<T>&, const Vector&);
// ...
};

template<class T> class Matrix {
Vector<T> v[4];
public:
friend Vector<T> operator*<>(const Matrix&, const Vector<T>&);
// ...
};

Te <> after the name of the friend function is needed to make clear that
the friend is a template function. Without the <>, a non-template
function would be assumed.

========================= end quote ==================================
Christophe Barbe
Guest
 
Posts: n/a
#3: Jul 19 '05

re: Template Friend Function, GCC and C++ FAQ Lite


On Mon, 20 Oct 2003 23:52:08 +0200, Rolf Magnus wrote:[color=blue]
> gcc is right. In chapter C.13.2 of TC++PL3, Stroustrup writes an
> example:[/color]

Thanks.
So VC++ is wrong (which is not really a surprise) and the faq has to be
updated. For the former I can do nothing, I will contact the author of the
C++ FAQ lite.

Thanks again,
Christophe
Closed Thread