Problem with a template class & friend function

Discussion in 'C++' started by mast2as@yahoo.com, Aug 7, 2006.

  1. Guest

    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
     
    , Aug 7, 2006
    #1
    1. Advertising

  2. wrote:
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 8, 2006
    #2
    1. Advertising

  3. Guest

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

    mark -


    Victor Bazarov wrote:
    > wrote:
    > > 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
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask
     
    , Aug 8, 2006
    #3
  4. Guest

    Victor Bazarov wrote:
    > wrote:
    > > 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 ?

    >> FOO.HPP <<


    #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_;
    };

    >> FOO.CPP <<


    #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_; }

    template class Foo<int>;

    >> MAIN.CPP <<


    #include "foo.hpp"

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

    >> COMPILING <<


    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
     
    , Aug 8, 2006
    #4
  5. wrote:
    > [...]
    > 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


    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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 8, 2006
    #5
  6. Guest

    >
    > 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
     
    , Aug 8, 2006
    #6
  7. wrote:
    >> 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 ?


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

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 9, 2006
    #7
  8. Guest

    > > 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.


    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
    ;-)
     
    , Aug 9, 2006
    #8
  9. wrote:
    >>> 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.

    >
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Aug 9, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Yueh-Wei Hu
    Replies:
    0
    Views:
    451
    Yueh-Wei Hu
    May 23, 2004
  2. Replies:
    2
    Views:
    483
    John Harrison
    Nov 9, 2005
  3. =?gb2312?B?wfXquw==?=
    Replies:
    10
    Views:
    701
    Victor Bazarov
    Aug 1, 2007
  4. Replies:
    2
    Views:
    675
    Triple-DES
    Feb 26, 2008
  5. A L
    Replies:
    1
    Views:
    512
    Alf P. Steinbach /Usenet
    Aug 25, 2010
Loading...

Share This Page