Friend function of a template class

Discussion in 'C++' started by Ruben Campos, Oct 28, 2004.

  1. Ruben Campos

    Ruben Campos Guest

    I have a problem with a template function that is declared as a friend of a
    template class. I'll first show the exact problem with source code:

    // MyClass.hpp
    template <typename T>
    class MyClass
    {
    // ...
    friend void MyFriendFunction (MyClass <T> * const ptrMyClass);
    // ...
    };

    #include "MyClass.cpp"


    // MyClass.cpp
    // ...
    template <typename T>
    void
    MyFriendFunction (MyClass <T> * const ptrMyClass)
    {
    // ...
    }
    // ...

    // Main.cpp
    #include "MyClass.hpp"

    int
    main (int argn, char ** argv)
    {
    MyClass <float> x;

    MyFriendFunction(&x);

    return 0;
    }

    Although MyClass <T> is a template, I still prefer to place the
    implementation of its methods in a MyClass.cpp file, and not to show them
    with the class declaration. But because MyClass <T> is a template, and so it
    needs method definitions visible in its header file, I include MyClass.cpp
    file inside MyClass.hpp file instead of building it (I don't compile
    MyClass.cpp). I've tried before this file scheme, and it works fine.

    Trying to build this, I receive an linker undefined external error for the
    MyFriendFunction (...) symbol. I've tried two alternative ways:

    a) Including the MyFriendFunction definition directly into MyClass.hpp,
    after (outside) class declaration. This returns the same linker error.

    b) Including the MyFriendFunction implementation directly into declaration,
    into MyClass.hpp inside class declaration. This works fine and don't return
    any error.

    But I don't want function implementations inside class declaration, or
    merely inside a header file. Can you help me with this? Thank you very much
    in advance.
    Ruben Campos, Oct 28, 2004
    #1
    1. Advertising

  2. Ruben Campos wrote in news:clqeku$rb1$ in comp.lang.c++:

    > I have a problem with a template function that is declared as a friend
    > of a template class. I'll first show the exact problem with source
    > code:
    >


    /* Forward Declaration's
    */

    template <typename T>
    class MyClass;

    template <typename T>
    void
    MyFriendFunction (MyClass <T> * const ptrMyClass);

    > // MyClass.hpp
    > template <typename T>
    > class MyClass
    > {
    > // ...
    > friend void MyFriendFunction (MyClass <T> * const ptrMyClass);


    friend void MyFriendFunction<> (MyClass <T> * const ptrMyClass);

    Note the <>.

    > // ...
    > };
    >
    > #include "MyClass.cpp"
    >
    >
    > // MyClass.cpp
    > // ...
    > template <typename T>
    > void
    > MyFriendFunction (MyClass <T> * const ptrMyClass)
    > {
    > // ...
    > }
    > // ...
    >
    > // Main.cpp
    > #include "MyClass.hpp"
    >
    > int
    > main (int argn, char ** argv)
    > {
    > MyClass <float> x;
    >
    > MyFriendFunction(&x);
    >
    > return 0;
    > }
    >


    >
    > Trying to build this, I receive an linker undefined external error for
    > the MyFriendFunction (...) symbol. I've tried two alternative ways:
    >


    Yep, you were declaring the friend function as a non-template.

    > a) Including the MyFriendFunction definition directly into
    > MyClass.hpp, after (outside) class declaration. This returns the same
    > linker error.
    >


    Your #include "MyClass.cpp" does exactly that.

    > b) Including the MyFriendFunction implementation directly into
    > declaration, into MyClass.hpp inside class declaration. This works
    > fine and don't return any error.


    Yes, its the only way to give the non-template declaration a defenition.

    Also your are right to want to avoid this as it often leads to problems:

    template < typename U, typename V >
    struct X
    {
    friend void f( U * ) {};
    };

    X< int, int > xii;
    /* Ok */

    X< int, short > xis;
    /* Whoopse: A defenition for f( int * ) has already been given */

    HTH.

    Rob.
    --
    http://www.victim-prime.dsl.pipex.com/
    Rob Williscroft, Oct 28, 2004
    #2
    1. Advertising

  3. Ruben Campos

    Ruben Campos Guest

    I've tried your solution. The linker undefined external error don't appear
    now, and all works fine. I supposed that MyFriendFunction was a template
    function due to its declaration inside a template class, but I was obviously
    wrong.

    Thank you very much for your help.


    "Rob Williscroft" <> escribió en el mensaje
    news:Xns95906E2393D5DukcoREMOVEfreenetrtw@130.133.1.4...
    > Ruben Campos wrote in news:clqeku$rb1$ in comp.lang.c++:
    >
    >> I have a problem with a template function that is declared as a friend
    >> of a template class. I'll first show the exact problem with source
    >> code:
    >>

    >
    > /* Forward Declaration's
    > */
    >
    > template <typename T>
    > class MyClass;
    >
    > template <typename T>
    > void
    > MyFriendFunction (MyClass <T> * const ptrMyClass);
    >
    >> // MyClass.hpp
    >> template <typename T>
    >> class MyClass
    >> {
    >> // ...
    >> friend void MyFriendFunction (MyClass <T> * const ptrMyClass);

    >
    > friend void MyFriendFunction<> (MyClass <T> * const ptrMyClass);
    >
    > Note the <>.
    >
    >> // ...
    >> };
    >>
    >> #include "MyClass.cpp"
    >>
    >>
    >> // MyClass.cpp
    >> // ...
    >> template <typename T>
    >> void
    >> MyFriendFunction (MyClass <T> * const ptrMyClass)
    >> {
    >> // ...
    >> }
    >> // ...
    >>
    >> // Main.cpp
    >> #include "MyClass.hpp"
    >>
    >> int
    >> main (int argn, char ** argv)
    >> {
    >> MyClass <float> x;
    >>
    >> MyFriendFunction(&x);
    >>
    >> return 0;
    >> }
    >>

    >
    >>
    >> Trying to build this, I receive an linker undefined external error for
    >> the MyFriendFunction (...) symbol. I've tried two alternative ways:
    >>

    >
    > Yep, you were declaring the friend function as a non-template.
    >
    >> a) Including the MyFriendFunction definition directly into
    >> MyClass.hpp, after (outside) class declaration. This returns the same
    >> linker error.
    >>

    >
    > Your #include "MyClass.cpp" does exactly that.
    >
    >> b) Including the MyFriendFunction implementation directly into
    >> declaration, into MyClass.hpp inside class declaration. This works
    >> fine and don't return any error.

    >
    > Yes, its the only way to give the non-template declaration a defenition.
    >
    > Also your are right to want to avoid this as it often leads to problems:
    >
    > template < typename U, typename V >
    > struct X
    > {
    > friend void f( U * ) {};
    > };
    >
    > X< int, int > xii;
    > /* Ok */
    >
    > X< int, short > xis;
    > /* Whoopse: A defenition for f( int * ) has already been given */
    >
    > HTH.
    >
    > Rob.
    > --
    > http://www.victim-prime.dsl.pipex.com/
    Ruben Campos, Oct 28, 2004
    #3
    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:
    448
    Yueh-Wei Hu
    May 23, 2004
  2. Replies:
    2
    Views:
    478
    John Harrison
    Nov 9, 2005
  3. =?gb2312?B?wfXquw==?=
    Replies:
    10
    Views:
    698
    Victor Bazarov
    Aug 1, 2007
  4. Replies:
    2
    Views:
    668
    Triple-DES
    Feb 26, 2008
  5. A L
    Replies:
    1
    Views:
    510
    Alf P. Steinbach /Usenet
    Aug 25, 2010
Loading...

Share This Page