Problem with a template class & friend function

M

mast2as

Hi guys, I think from what I found on the net that the code is correct
and there's no problem when I compile the files. The problems occurs
when I link them. I have a friend function which outputs points data to
the ostream. Here is the error message:

objs/generalpolygons.o(.text+0xf08): In function
`GeneralPolygons::readObjFile(std::basic_string<char,
std::char_traits<char>, std::allocator<char> >)':
core/generalpolygons.cpp:222: undefined reference to
`std::basic_ostream<char, std::char_traits<char> >& operator<<
<float>(std::basic_ostream<char, std::char_traits<char> >&,
Point<float> const&)'

Here is the code:

In point.hpp

// foward declaration needed for the template friend functions
template<typename T> class Point;
// forward declarion of the Point's friend function
template<typename T> std::eek:stream & operator<<( std::eek:stream &os,
const Point<T> &p );

template<typename T>
class Point
{
public:
...
friend std::eek:stream & operator<< <T>( std::eek:stream &os, const
Point<T> &p );
};

in point.cpp

template<typename T>
std::eek:stream & operator<<(std::eek:stream &os, const Point<T> &p )
{
os << p.x << " " << p.y << " " << p.z;
return os;
}

how I use it in the code

std::cout << Point<float>( 0.0 ) << std::endl;

Thanks for your help, Mark
 
V

Victor Bazarov

Hi guys, I think from what I found on the net that the code is correct
and there's no problem when I compile the files. The problems occurs
when I link them. [..]

This is in the FAQ. See section 35.

V
 
M

mast2as

I see ... should make a habit to check the faq first.
Thanks, I made the change and it works fine now.

mark -


Victor said:
Hi guys, I think from what I found on the net that the code is correct
and there's no problem when I compile the files. The problems occurs
when I link them. [..]

This is in the FAQ. See section 35.

V
 
M

mast2as

Victor said:
Hi guys, I think from what I found on the net that the code is correct
and there's no problem when I compile the files. The problems occurs
when I link them. [..]

This is in the FAQ. See section 35.

I am sorry Victor but I actually compiled the example of the FAQ and I
get the same error. I don't really understand ?

#include <iostream>

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::eek:stream& operator<< (std::eek:stream& o, const
Foo<T>& x);

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

#include "foo.hpp"

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::eek:stream& operator<< (std::eek:stream& o, const Foo<T>& x)
{ return o << x.value_; }


#include "foo.hpp"

int main()
{
Foo<int> lhs(1);
Foo<int> rhs(2);
Foo<int> result = lhs + rhs;
std::cout << result;
}

c++ -c foo.cpp
c++ -c main.cpp
c++ -o main main.o foo.o

main.o(.text+0x63): In function `main':
: undefined reference to `Foo<int> operator+<int>(Foo<int> const&,
Foo<int> const&)'
main.o(.text+0x7f): In function `main':
: undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& operator<< <int>(std::basic_ostream<char,
std::char_traits<char> >&, Foo<int> const&)'
collect2: ld returned 1 exit status
 
V

Victor Bazarov

[...]
main.o(.text+0x63): In function `main':
undefined reference to `Foo<int> operator+<int>(Foo<int> const&,
Foo said:
undefined reference to `std::basic_ostream<char,
std::char_traits<char> >& operator<< <int>(std::basic_ostream<char,
std::char_traits<char> >&, Foo<int> const&)'
collect2: ld returned 1 exit status

You instantiated Foo<int>. That instantiates all members of that
class. But it does *not* instantiate non-member functions. If you
want to instantiate those, you need two more explicit instantiations.

V
 
M

mast2as

You instantiated Foo<int>. That instantiates all members of that
class. But it does *not* instantiate non-member functions. If you
want to instantiate those, you need two more explicit instantiations.

Thanks Victor I did the change and now it works fine. Wouldn't it be
worth making the change to the example in the FAQ as well though. In
it's current form, the example won't work ?

-m
 
V

Victor Bazarov

Thanks Victor I did the change and now it works fine. Wouldn't it be
worth making the change to the example in the FAQ as well though. In
it's current form, the example won't work ?

What do *you* think? Take the example as is and try it.

V
 
M

mast2as

Thanks Victor I did the change and now it works fine. Wouldn't it be
What do *you* think? Take the example as is and try it.

Sorry I wasn't clear but it's no big deal. I tried the example and it
didn't compile (link) for the reason you mentionned to me. So my
suggestion was that if someone else with little knowledge of C++ was
trying like i did, to compile that same example it won't work for that
other person either, hence the idea of making that small change to the
code in the FAQ, but I wanted the opinion of someone who knows better
;-)
 
V

Victor Bazarov

Sorry I wasn't clear but it's no big deal. I tried the example and it
didn't compile (link) for the reason you mentionned to me.

You took it without changing and it didn't work? I just checked 35.15,
and all suggestions worked for me. What is it that didn't work for you?
Read FAQ 5.8 and follow its suggestions. Start another thread if need
be.

Or, did you take the example, then *changed* it, and *then* it didn't
work? I can't help you with that. We cannot anticipate *all* possible
changes one can make to the examples in the FAQ to make them wrong. So
the advice is "don't".
So my
suggestion was that if someone else with little knowledge of C++ was
trying like i did, to compile that same example

Again, changed or not changed? Not changed, it works fine. If it does
not, the compiler is probably somehow disabled (retarded).
it won't work for that
other person either, hence the idea of making that small change to the
code in the FAQ, but I wanted the opinion of someone who knows better
;-)

Please contact Marshall Cline ans suggest the change. You will need to
actually formulate it instead of saying "I tried and it didn't work".

V
 

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,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top