Howto declare a friend function to a nested class

Discussion in 'C++' started by jdurancomas@gmail.com, Sep 30, 2007.

  1. Guest

    Dear all,

    I'm trying to declare the operator++ to a nested class. The nested
    class is not template but the container it is.

    The code used in teh sample program is included bellow:


    #include <iostream>


    template <class T>
    class A
    {
    public:
    class B;
    };


    template <class T>
    bool operator == <T> (const A<T>::B &b1,
    const class A<T>::B &b2);


    template <class T>
    class A<T>::B
    {
    public:
    B(int a);

    friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);

    private:
    int aa;
    B b;
    };


    template <class T>
    A<T>::B::B(int a):
    aa(a)
    {}


    template <class T>
    bool operator == <>(const A<T>::B& b1, const A<T>::B& b2)
    {
    return b1.aa == b2.aa;
    }


    class C {};


    int main()
    {
    A<C> ac;

    A<C>::B b1(4), b2(5);

    bool res = (b1 == b2);
    return 0;
    }


    I'm compiling with gcc version 4.1.2. The output of the compiler is
    included bellow:

    nested.cpp:13: error: expected initializer before '<' token
    nested.cpp:23: error: expected unqualified-id before 'template'
    nested.cpp:38: error: expected initializer before '<' token
    nested.cpp: In instantiation of 'A<C>::B':
    nested.cpp:51: instantiated from here
    nested.cpp:27: error: 'A<T>::B::b' has incomplete type
    nested.cpp:19: error: declaration of 'class A<C>::B'
    nested.cpp: In function 'int main()':
    nested.cpp:53: error: no match for 'operator==' in 'b1 == b2'

    Any help will be appreciated.

    Thanks and Best Regards,
    Joaquim Duran
     
    , Sep 30, 2007
    #1
    1. Advertising

  2. wrote:
    > [..]
    > template <class T>
    > class A<T>::B
    > {
    > public:
    > B(int a);
    >
    > friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);
    >
    > private:
    > int aa;
    > B b;


    Am I reading this right? An instance of your 'B' class contains
    another instance of the same class, 'b'? Not gonna work.

    Fix this first, then post the corrected code again.

    And keep in mind that a member of a class template _is_ essentially
    a template itself.

    > };
    > [..]


    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, Sep 30, 2007
    #2
    1. Advertising

  3. * :
    > Dear all,
    >
    > I'm trying to declare the operator++ to a nested class. The nested
    > class is not template but the container it is.
    >
    > The code used in teh sample program is included bellow:
    >
    >
    > #include <iostream>
    >
    >
    > template <class T>
    > class A
    > {
    > public:
    > class B;
    > };
    >
    >
    > template <class T>
    > bool operator == <T> (const A<T>::B &b1,
    > const class A<T>::B &b2);
    >
    >
    > template <class T>
    > class A<T>::B
    > {
    > public:
    > B(int a);
    >
    > friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);
    >
    > private:
    > int aa;
    > B b;
    > };
    >
    >
    > template <class T>
    > A<T>::B::B(int a):
    > aa(a)
    > {}
    >
    >
    > template <class T>
    > bool operator == <>(const A<T>::B& b1, const A<T>::B& b2)
    > {
    > return b1.aa == b2.aa;
    > }
    >
    >
    > class C {};
    >
    >
    > int main()
    > {
    > A<C> ac;
    >
    > A<C>::B b1(4), b2(5);
    >
    > bool res = (b1 == b2);
    > return 0;
    > }
    >
    >
    > I'm compiling with gcc version 4.1.2. The output of the compiler is
    > included bellow:
    >
    > nested.cpp:13: error: expected initializer before '<' token
    > nested.cpp:23: error: expected unqualified-id before 'template'
    > nested.cpp:38: error: expected initializer before '<' token
    > nested.cpp: In instantiation of 'A<C>::B':
    > nested.cpp:51: instantiated from here
    > nested.cpp:27: error: 'A<T>::B::b' has incomplete type
    > nested.cpp:19: error: declaration of 'class A<C>::B'
    > nested.cpp: In function 'int main()':
    > nested.cpp:53: error: no match for 'operator==' in 'b1 == b2'
    >
    > Any help will be appreciated.


    Add "typename" before the dependent types.

    Cheers, & hth.,

    - Alf


    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Sep 30, 2007
    #3
  4. Guest

    On 30 Set, 02:15, "Victor Bazarov" <> wrote:
    > wrote:
    > > [..]
    > > template <class T>
    > > class A<T>::B
    > > {
    > > public:
    > > B(int a);

    >
    > > friend bool operator ==<> (const A<T>::B &b1, const A<T>::B &b2);

    >
    > > private:
    > > int aa;
    > > B b;

    >
    > Am I reading this right? An instance of your 'B' class contains
    > another instance of the same class, 'b'? Not gonna work.
    >
    > Fix this first, then post the corrected code again.
    >
    > And keep in mind that a member of a class template _is_ essentially
    > a template itself.
    >
    > > };
    > > [..]

    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    I agree, in the sample, I've declared a recursive type that C++ is not
    supporting. I've removed it, and I've improved the syntax (adding
    typename as suggested, thanks). Now, the only error is the declaration
    of a friend template function.


    Improved source code:

    #include <iostream>


    template <typename T>
    class A
    {
    public:
    class B;
    };


    /* Example of template function */
    template <typename T>
    T add(T a, T b) {return a+b;}


    template <typename T>
    bool operator == (const typename A<T>::B &b1,
    const typename A<T>::B &b2);


    template <typename T>
    class A<T>::B
    {
    public:
    B(int a);

    friend bool operator == <> (const typename A<T>::B &b1,
    const typename A<T>::B &b2); // Line 29

    private:
    int aa;
    };


    template <typename T>
    A<T>::B::B(int a):
    aa(a)
    {}


    template <typename T>
    bool operator == (const typename A<T>::B& b1,
    const typename A<T>::B& b2)
    {
    return b1.aa == b2.aa;
    }


    class C {};


    int main()
    {
    A<C>::B b1(4), b2(5);

    bool res = (b1 == b2); // Line 57
    return 0;
    }


    The message error from compiler is:

    nested.cpp: In instantiation of 'A<C>::B':
    nested.cpp:55: instantiated from here
    nested.cpp:29: error: template-id 'operator==<>' for 'bool
    operator==(const A<C>::B&, const A<C>::B&)' does not match any
    template declaration
    nested.cpp: In function 'int main()':
    nested.cpp:57: error: no match for 'operator==' in 'b1 == b2'

    I've googled a litle abut how declare template functions as friends,
    and It looks likes that the current syntax is right.

    Thanks and Best Regads,
    Joaquim Duran
     
    , Sep 30, 2007
    #4
  5. wrote:
    > [...]
    > Improved source code:
    >
    > #include <iostream>
    >
    >
    > template <typename T>
    > class A
    > {
    > public:
    > class B;
    > };
    >
    >
    > /* Example of template function */
    > template <typename T>
    > T add(T a, T b) {return a+b;}
    >
    >
    > template <typename T>
    > bool operator == (const typename A<T>::B &b1,
    > const typename A<T>::B &b2);
    >
    >
    > template <typename T>
    > class A<T>::B
    > {
    > public:
    > B(int a);
    >
    > friend bool operator == <> (const typename A<T>::B &b1,


    Should be

    friend bool operator == <T> ...

    > const typename A<T>::B &b2); // Line 29
    >
    > private:
    > int aa;
    > };
    >
    >
    > template <typename T>
    > A<T>::B::B(int a):
    > aa(a)
    > {}
    >
    >
    > template <typename T>
    > bool operator == (const typename A<T>::B& b1,
    > const typename A<T>::B& b2)
    > {
    > return b1.aa == b2.aa;
    > }
    >
    >
    > class C {};
    >
    >
    > int main()
    > {
    > A<C>::B b1(4), b2(5);
    >
    > bool res = (b1 == b2); // Line 57


    There is no way for the compiler to determine that the template
    operator should be used because from the expression 'b1 == b2'
    the compiler cannot deduce the 'C' for the template -- the context
    is not one of the deducible contexts.

    > return 0;
    > }
    >
    >
    > The message error from compiler is:
    >
    > nested.cpp: In instantiation of 'A<C>::B':
    > nested.cpp:55: instantiated from here
    > nested.cpp:29: error: template-id 'operator==<>' for 'bool
    > operator==(const A<C>::B&, const A<C>::B&)' does not match any
    > template declaration


    That can be rectified by placing 'T' in the angle brackets, see
    above.

    > nested.cpp: In function 'int main()':
    > nested.cpp:57: error: no match for 'operator==' in 'b1 == b2'


    This cannot be corrected because the compiler canno deduce the 'T'
    for the template operator==

    > I've googled a litle abut how declare template functions as friends,
    > and It looks likes that the current syntax is right.


    Apparently it wasn't.

    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, Sep 30, 2007
    #5
    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. request@no_spam.com
    Replies:
    5
    Views:
    458
  2. freegnu
    Replies:
    2
    Views:
    351
    freegnu
    Oct 23, 2006
  3. Replies:
    1
    Views:
    1,412
    Jim Langston
    Nov 9, 2006
  4. =?gb2312?B?wfXquw==?=
    Replies:
    10
    Views:
    716
    Victor Bazarov
    Aug 1, 2007
  5. Replies:
    2
    Views:
    698
    Triple-DES
    Feb 26, 2008
Loading...

Share This Page