Returning a private nested class of a class template

Discussion in 'C++' started by ymost@hotmail.com, Dec 31, 2008.

  1. Guest

    Hi,
    I have a class with a friend function that returns an instance of a
    private nested class:

    //--------------------------------------------------
    class A {
    class B {};
    friend B func(double x);
    };

    A::B func(double x) {return A::B();}

    int main() {
    func(1.2);
    return 0;
    }
    //------------------------------------------------

    This code compiles and runs on the MS Visual C++ 2008 compiler.
    However, if I use a class template instead:

    //--------------------------------------------------
    template<typename T> class A {
    class B {};
    friend B func(T x);
    };

    template<typename T> typename A<T>::B func(T x) {return A<T>::B();}

    int main() {
    func(1.2); // <-- error received here
    return 0;
    }
    //------------------------------------------------

    I get an error:
    error C2248: 'A<T>::B' : cannot access private class declared in class
    'A<T>'.
    Notice the error is in 'main', and not in the function definition, so
    I don't think the problem is with the friend declaration.

    So is returning an instance of a private nested class legal or not?
    , Dec 31, 2008
    #1
    1. Advertising

  2. red floyd Guest

    wrote:
    > Hi,
    > I have a class with a friend function that returns an instance of a
    > private nested class:
    >
    > //--------------------------------------------------
    > class A {
    > class B {};
    > friend B func(double x);
    > };
    >
    > A::B func(double x) {return A::B();}
    >
    > int main() {
    > func(1.2);
    > return 0;
    > }
    > //------------------------------------------------
    >
    > This code compiles and runs on the MS Visual C++ 2008 compiler.
    > However, if I use a class template instead:
    >
    > //--------------------------------------------------
    > template<typename T> class A {
    > class B {};
    > friend B func(T x);
    > };
    >
    > template<typename T> typename A<T>::B func(T x) {return A<T>::B();}
    >
    > int main() {
    > func(1.2); // <-- error received here
    > return 0;
    > }
    > //------------------------------------------------
    >
    > I get an error:
    > error C2248: 'A<T>::B' : cannot access private class declared in class
    > 'A<T>'.
    > Notice the error is in 'main', and not in the function definition, so
    > I don't think the problem is with the friend declaration.
    >
    > So is returning an instance of a private nested class legal or not?


    No, it's not legal, because the destructor for the private class needs
    to run.
    red floyd, Jan 1, 2009
    #2
    1. Advertising

  3. James Kanze Guest

    On Jan 1, 1:15 am, red floyd <> wrote:
    > wrote:


    > > I have a class with a friend function that returns an
    > > instance of a private nested class:


    > > //--------------------------------------------------
    > > class A {
    > > class B {};
    > > friend B func(double x);
    > > };


    > > A::B func(double x) {return A::B();}


    > > int main() {
    > > func(1.2);
    > > return 0;
    > > }
    > > //------------------------------------------------


    > > This code compiles and runs on the MS Visual C++ 2008
    > > compiler. However, if I use a class template instead:


    > > //--------------------------------------------------
    > > template<typename T> class A {
    > > class B {};
    > > friend B func(T x);
    > > };


    > > template<typename T> typename A<T>::B func(T x) {return A<T>::B();}


    > > int main() {
    > > func(1.2); // <-- error received here
    > > return 0;
    > > }
    > > //------------------------------------------------


    > > I get an error:
    > > error C2248: 'A<T>::B' : cannot access private class declared in class
    > > 'A<T>'.
    > > Notice the error is in 'main', and not in the function
    > > definition, so I don't think the problem is with the friend
    > > declaration.


    > > So is returning an instance of a private nested class legal
    > > or not?


    > No, it's not legal, because the destructor for the private
    > class needs to run.


    And the standard says explicitly that this is checked in the
    context of the call.

    Which doesn't explain whey the non-template version compiled.
    It shouldn't, either.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Jan 1, 2009
    #3
  4. Bertrand Guest

    James Kanze wrote:
    > On Jan 1, 1:15 am, red floyd <> wrote:
    >> wrote:

    >
    >>> I have a class with a friend function that returns an
    >>> instance of a private nested class:

    >
    >>> //--------------------------------------------------
    >>> class A {
    >>> class B {};
    >>> friend B func(double x);
    >>> };

    >
    >>> A::B func(double x) {return A::B();}

    >
    >>> int main() {
    >>> func(1.2);
    >>> return 0;
    >>> }
    >>> //------------------------------------------------

    >
    >>> This code compiles and runs on the MS Visual C++ 2008
    >>> compiler. However, if I use a class template instead:

    >
    >>> //--------------------------------------------------
    >>> template<typename T> class A {
    >>> class B {};
    >>> friend B func(T x);
    >>> };

    >
    >>> template<typename T> typename A<T>::B func(T x) {return A<T>::B();}

    >
    >>> int main() {
    >>> func(1.2); // <-- error received here
    >>> return 0;
    >>> }
    >>> //------------------------------------------------

    >
    >>> I get an error:
    >>> error C2248: 'A<T>::B' : cannot access private class declared in class
    >>> 'A<T>'.
    >>> Notice the error is in 'main', and not in the function
    >>> definition, so I don't think the problem is with the friend
    >>> declaration.

    >
    >>> So is returning an instance of a private nested class legal
    >>> or not?

    >
    >> No, it's not legal, because the destructor for the private
    >> class needs to run.

    >
    > And the standard says explicitly that this is checked in the
    > context of the call.
    >
    > Which doesn't explain whey the non-template version compiled.
    > It shouldn't, either.
    >

    To clarify, and for my own understanding, the issue here is only related
    to the fact that A<T>::B is returned from a non-member function, right?

    I don't get any problem with something like (g++ 4.3.2):
    ~~~
    template< typename T >
    class A
    {
    class B {};
    public:
    B getB() const
    { return B(); }
    };
    int main(int argc, char const** argv)
    {
    A<double>().getB();
    A<int>().getB();
    return 0;
    }
    ~~~

    Once I found useful to return a private class which acts as a proxy in
    the implementation of an iterator. *i returns the private nested class
    which implements the operator=, for an output iterator, for example.

    Also, g++ 4.3.2 and online comeau compiler compile without problem the
    non-template version of the friend function returning a private nested
    class (first example given in the original post).
    Bertrand, Jan 10, 2009
    #4
    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.

Share This Page