C
Christophe Barbe
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:stream& operator<<(std:stream&,
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:stream& operator<< (std:stream& 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:stream& operator<< __TFS__ (std:stream& 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:stream& operator<< (std:stream& o, const Foo<T>& x)
{
return o << x.value_;
}
---- end of foo.h ----
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:stream& operator<<(std:stream&,
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:stream& operator<< (std:stream& 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:stream& operator<< __TFS__ (std:stream& 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:stream& operator<< (std:stream& o, const Foo<T>& x)
{
return o << x.value_;
}
---- end of foo.h ----