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

Template Friend Function, GCC and C++ FAQ Lite

P: n/a
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 ----
Jul 19 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Christophe Barbe wrote:
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 containers-and-templates.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?


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 ==================================
Jul 19 '05 #2

P: n/a
On Mon, 20 Oct 2003 23:52:08 +0200, Rolf Magnus wrote:
gcc is right. In chapter C.13.2 of TC++PL3, Stroustrup writes an
example:


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
Jul 19 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.