Use the using directive on a private nested class

Multi tool use
Multi tool use












1















I have been developing a library for a while and now that I think it's ready, I am trying to follow the pimpl principle in order to hide implementation details.



// File Class.h
class Class {
public:
Class();

private:
class ClassImpl;
ClassImpl* rep;
};

// File Class.cpp
#include "Class.h"
#include "ClassImpl.h"
Class::Class() {
rep = new ClassImpl();
}


The implementation class is defined in another file as follow



// File ClassImpl.h
#include "Class.h"
class Class::ClassImpl {
public:
ClassImpl();
};


And its implementation:



// File ClassImpl.cpp
#include "ClassImpl.h"
#include <iostream>

using C = Class::ClassImpl; // error: 'class Class::ClassImpl' is private
C::ClassImpl() {
std::cout << "Implementation constructor";
}


Main function:



// File main.cpp
#include "Class.h"
int main() {
Class c;
return 0;
}


Doing this, the compiler says error: 'class Class::ClassImpl' is private on the using line in ClassImpl.cpp. If I remove it and use Class::ClassImpl instead, everything works fine.



Is there a way to use usingon the private nested class ClassImpl ?










share|improve this question

























  • Does the example at the end of the page, that you refer to, do the same thing as you? Do they also try to use using and the impl of the widget class in the main() function? No.

    – Joey Mallone
    Jan 2 at 11:31













  • @JoeyMallone no because they define the function inside the class declaration. It seems a good idea in the example page but because my implementation is hundred-of-line-long, then it is not adequate to me

    – Xatyrian
    Jan 2 at 11:35











  • try this ClassImpl::ClassImpl() { for the constructor and leave using.

    – Joey Mallone
    Jan 2 at 11:37













  • I have nothing to back up this claim (hence only as a comment), but no, it is not possible. You are trying to create an alias. Imagine if you could create an alias to any private symbol. That would break the entire purpose of access modifiers, wouldn't it? Anyhow, although I hate the precompiler, you can achieve the same code reduction by simply defining a constant: #define C Class::ClassImpl

    – Kiruse
    Jan 2 at 11:38


















1















I have been developing a library for a while and now that I think it's ready, I am trying to follow the pimpl principle in order to hide implementation details.



// File Class.h
class Class {
public:
Class();

private:
class ClassImpl;
ClassImpl* rep;
};

// File Class.cpp
#include "Class.h"
#include "ClassImpl.h"
Class::Class() {
rep = new ClassImpl();
}


The implementation class is defined in another file as follow



// File ClassImpl.h
#include "Class.h"
class Class::ClassImpl {
public:
ClassImpl();
};


And its implementation:



// File ClassImpl.cpp
#include "ClassImpl.h"
#include <iostream>

using C = Class::ClassImpl; // error: 'class Class::ClassImpl' is private
C::ClassImpl() {
std::cout << "Implementation constructor";
}


Main function:



// File main.cpp
#include "Class.h"
int main() {
Class c;
return 0;
}


Doing this, the compiler says error: 'class Class::ClassImpl' is private on the using line in ClassImpl.cpp. If I remove it and use Class::ClassImpl instead, everything works fine.



Is there a way to use usingon the private nested class ClassImpl ?










share|improve this question

























  • Does the example at the end of the page, that you refer to, do the same thing as you? Do they also try to use using and the impl of the widget class in the main() function? No.

    – Joey Mallone
    Jan 2 at 11:31













  • @JoeyMallone no because they define the function inside the class declaration. It seems a good idea in the example page but because my implementation is hundred-of-line-long, then it is not adequate to me

    – Xatyrian
    Jan 2 at 11:35











  • try this ClassImpl::ClassImpl() { for the constructor and leave using.

    – Joey Mallone
    Jan 2 at 11:37













  • I have nothing to back up this claim (hence only as a comment), but no, it is not possible. You are trying to create an alias. Imagine if you could create an alias to any private symbol. That would break the entire purpose of access modifiers, wouldn't it? Anyhow, although I hate the precompiler, you can achieve the same code reduction by simply defining a constant: #define C Class::ClassImpl

    – Kiruse
    Jan 2 at 11:38
















1












1








1








I have been developing a library for a while and now that I think it's ready, I am trying to follow the pimpl principle in order to hide implementation details.



// File Class.h
class Class {
public:
Class();

private:
class ClassImpl;
ClassImpl* rep;
};

// File Class.cpp
#include "Class.h"
#include "ClassImpl.h"
Class::Class() {
rep = new ClassImpl();
}


The implementation class is defined in another file as follow



// File ClassImpl.h
#include "Class.h"
class Class::ClassImpl {
public:
ClassImpl();
};


And its implementation:



// File ClassImpl.cpp
#include "ClassImpl.h"
#include <iostream>

using C = Class::ClassImpl; // error: 'class Class::ClassImpl' is private
C::ClassImpl() {
std::cout << "Implementation constructor";
}


Main function:



// File main.cpp
#include "Class.h"
int main() {
Class c;
return 0;
}


Doing this, the compiler says error: 'class Class::ClassImpl' is private on the using line in ClassImpl.cpp. If I remove it and use Class::ClassImpl instead, everything works fine.



Is there a way to use usingon the private nested class ClassImpl ?










share|improve this question
















I have been developing a library for a while and now that I think it's ready, I am trying to follow the pimpl principle in order to hide implementation details.



// File Class.h
class Class {
public:
Class();

private:
class ClassImpl;
ClassImpl* rep;
};

// File Class.cpp
#include "Class.h"
#include "ClassImpl.h"
Class::Class() {
rep = new ClassImpl();
}


The implementation class is defined in another file as follow



// File ClassImpl.h
#include "Class.h"
class Class::ClassImpl {
public:
ClassImpl();
};


And its implementation:



// File ClassImpl.cpp
#include "ClassImpl.h"
#include <iostream>

using C = Class::ClassImpl; // error: 'class Class::ClassImpl' is private
C::ClassImpl() {
std::cout << "Implementation constructor";
}


Main function:



// File main.cpp
#include "Class.h"
int main() {
Class c;
return 0;
}


Doing this, the compiler says error: 'class Class::ClassImpl' is private on the using line in ClassImpl.cpp. If I remove it and use Class::ClassImpl instead, everything works fine.



Is there a way to use usingon the private nested class ClassImpl ?







c++ class-visibility






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 11:51









YSC

25k557112




25k557112










asked Jan 2 at 11:27









XatyrianXatyrian

812320




812320













  • Does the example at the end of the page, that you refer to, do the same thing as you? Do they also try to use using and the impl of the widget class in the main() function? No.

    – Joey Mallone
    Jan 2 at 11:31













  • @JoeyMallone no because they define the function inside the class declaration. It seems a good idea in the example page but because my implementation is hundred-of-line-long, then it is not adequate to me

    – Xatyrian
    Jan 2 at 11:35











  • try this ClassImpl::ClassImpl() { for the constructor and leave using.

    – Joey Mallone
    Jan 2 at 11:37













  • I have nothing to back up this claim (hence only as a comment), but no, it is not possible. You are trying to create an alias. Imagine if you could create an alias to any private symbol. That would break the entire purpose of access modifiers, wouldn't it? Anyhow, although I hate the precompiler, you can achieve the same code reduction by simply defining a constant: #define C Class::ClassImpl

    – Kiruse
    Jan 2 at 11:38





















  • Does the example at the end of the page, that you refer to, do the same thing as you? Do they also try to use using and the impl of the widget class in the main() function? No.

    – Joey Mallone
    Jan 2 at 11:31













  • @JoeyMallone no because they define the function inside the class declaration. It seems a good idea in the example page but because my implementation is hundred-of-line-long, then it is not adequate to me

    – Xatyrian
    Jan 2 at 11:35











  • try this ClassImpl::ClassImpl() { for the constructor and leave using.

    – Joey Mallone
    Jan 2 at 11:37













  • I have nothing to back up this claim (hence only as a comment), but no, it is not possible. You are trying to create an alias. Imagine if you could create an alias to any private symbol. That would break the entire purpose of access modifiers, wouldn't it? Anyhow, although I hate the precompiler, you can achieve the same code reduction by simply defining a constant: #define C Class::ClassImpl

    – Kiruse
    Jan 2 at 11:38



















Does the example at the end of the page, that you refer to, do the same thing as you? Do they also try to use using and the impl of the widget class in the main() function? No.

– Joey Mallone
Jan 2 at 11:31







Does the example at the end of the page, that you refer to, do the same thing as you? Do they also try to use using and the impl of the widget class in the main() function? No.

– Joey Mallone
Jan 2 at 11:31















@JoeyMallone no because they define the function inside the class declaration. It seems a good idea in the example page but because my implementation is hundred-of-line-long, then it is not adequate to me

– Xatyrian
Jan 2 at 11:35





@JoeyMallone no because they define the function inside the class declaration. It seems a good idea in the example page but because my implementation is hundred-of-line-long, then it is not adequate to me

– Xatyrian
Jan 2 at 11:35













try this ClassImpl::ClassImpl() { for the constructor and leave using.

– Joey Mallone
Jan 2 at 11:37







try this ClassImpl::ClassImpl() { for the constructor and leave using.

– Joey Mallone
Jan 2 at 11:37















I have nothing to back up this claim (hence only as a comment), but no, it is not possible. You are trying to create an alias. Imagine if you could create an alias to any private symbol. That would break the entire purpose of access modifiers, wouldn't it? Anyhow, although I hate the precompiler, you can achieve the same code reduction by simply defining a constant: #define C Class::ClassImpl

– Kiruse
Jan 2 at 11:38







I have nothing to back up this claim (hence only as a comment), but no, it is not possible. You are trying to create an alias. Imagine if you could create an alias to any private symbol. That would break the entire purpose of access modifiers, wouldn't it? Anyhow, although I hate the precompiler, you can achieve the same code reduction by simply defining a constant: #define C Class::ClassImpl

– Kiruse
Jan 2 at 11:38














2 Answers
2






active

oldest

votes


















1















Is there a way to use using on the private nested class ClassImpl?




The short answer is "no".



Longer answer follows.



What you're trying to do is a using declaration, not a using directive.



Your using declaration




using C = Class::ClassImpl;



is at file scope, so the name Class::ClassImpl cannot be used directly as a name in that scope.



The first relevant section of the standard (C++17) is Section 10.3.3 "The using declaration", for which para 19 states "A synonym created by a using-declaration has the usual accessibility for a member-declaration".



To find what is meant by "usual accessibility", refer to Section 14 "Member Access Control", which states that "private names can only be used by members and friends of the class in which it is declared". The usage of "names" here is quite specific - anything with a name that is private to a class (member declarations, type declarations, etc) are treated the same way.



If you want to have a using declaration at file scope, as per your example;




using C = Class::ClassImpl;



then ClassImpl needs to be a public name (of a nested class) of Class. private and protected names of a class cannot be accessed at file scope.






share|improve this answer































    1















    Is there a way to use usingon the private nested class ClassImpl ?




    Yes. Declare ClassImpl with public access in Class:



    class Class {
    public:
    Class();
    class ClassImpl;

    private:
    ClassImpl* rep; // should be reference, see note.
    };

    // ...

    using C = Class::ClassImpl;


    Live demo



    You can also make ClassImpl not a nested class.



    Note: you might prefer having Class::rep to be a reference rather than a (naked) pointer. There is no reason for a valid Class instance not to have an implementation object (a null pointer).






    share|improve this answer


























    • The naked pointer was just for the example, I use smart pointers actually

      – Xatyrian
      Jan 2 at 15:12











    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005503%2fuse-the-using-directive-on-a-private-nested-class%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1















    Is there a way to use using on the private nested class ClassImpl?




    The short answer is "no".



    Longer answer follows.



    What you're trying to do is a using declaration, not a using directive.



    Your using declaration




    using C = Class::ClassImpl;



    is at file scope, so the name Class::ClassImpl cannot be used directly as a name in that scope.



    The first relevant section of the standard (C++17) is Section 10.3.3 "The using declaration", for which para 19 states "A synonym created by a using-declaration has the usual accessibility for a member-declaration".



    To find what is meant by "usual accessibility", refer to Section 14 "Member Access Control", which states that "private names can only be used by members and friends of the class in which it is declared". The usage of "names" here is quite specific - anything with a name that is private to a class (member declarations, type declarations, etc) are treated the same way.



    If you want to have a using declaration at file scope, as per your example;




    using C = Class::ClassImpl;



    then ClassImpl needs to be a public name (of a nested class) of Class. private and protected names of a class cannot be accessed at file scope.






    share|improve this answer




























      1















      Is there a way to use using on the private nested class ClassImpl?




      The short answer is "no".



      Longer answer follows.



      What you're trying to do is a using declaration, not a using directive.



      Your using declaration




      using C = Class::ClassImpl;



      is at file scope, so the name Class::ClassImpl cannot be used directly as a name in that scope.



      The first relevant section of the standard (C++17) is Section 10.3.3 "The using declaration", for which para 19 states "A synonym created by a using-declaration has the usual accessibility for a member-declaration".



      To find what is meant by "usual accessibility", refer to Section 14 "Member Access Control", which states that "private names can only be used by members and friends of the class in which it is declared". The usage of "names" here is quite specific - anything with a name that is private to a class (member declarations, type declarations, etc) are treated the same way.



      If you want to have a using declaration at file scope, as per your example;




      using C = Class::ClassImpl;



      then ClassImpl needs to be a public name (of a nested class) of Class. private and protected names of a class cannot be accessed at file scope.






      share|improve this answer


























        1












        1








        1








        Is there a way to use using on the private nested class ClassImpl?




        The short answer is "no".



        Longer answer follows.



        What you're trying to do is a using declaration, not a using directive.



        Your using declaration




        using C = Class::ClassImpl;



        is at file scope, so the name Class::ClassImpl cannot be used directly as a name in that scope.



        The first relevant section of the standard (C++17) is Section 10.3.3 "The using declaration", for which para 19 states "A synonym created by a using-declaration has the usual accessibility for a member-declaration".



        To find what is meant by "usual accessibility", refer to Section 14 "Member Access Control", which states that "private names can only be used by members and friends of the class in which it is declared". The usage of "names" here is quite specific - anything with a name that is private to a class (member declarations, type declarations, etc) are treated the same way.



        If you want to have a using declaration at file scope, as per your example;




        using C = Class::ClassImpl;



        then ClassImpl needs to be a public name (of a nested class) of Class. private and protected names of a class cannot be accessed at file scope.






        share|improve this answer














        Is there a way to use using on the private nested class ClassImpl?




        The short answer is "no".



        Longer answer follows.



        What you're trying to do is a using declaration, not a using directive.



        Your using declaration




        using C = Class::ClassImpl;



        is at file scope, so the name Class::ClassImpl cannot be used directly as a name in that scope.



        The first relevant section of the standard (C++17) is Section 10.3.3 "The using declaration", for which para 19 states "A synonym created by a using-declaration has the usual accessibility for a member-declaration".



        To find what is meant by "usual accessibility", refer to Section 14 "Member Access Control", which states that "private names can only be used by members and friends of the class in which it is declared". The usage of "names" here is quite specific - anything with a name that is private to a class (member declarations, type declarations, etc) are treated the same way.



        If you want to have a using declaration at file scope, as per your example;




        using C = Class::ClassImpl;



        then ClassImpl needs to be a public name (of a nested class) of Class. private and protected names of a class cannot be accessed at file scope.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jan 2 at 12:36









        PeterPeter

        27.8k32157




        27.8k32157

























            1















            Is there a way to use usingon the private nested class ClassImpl ?




            Yes. Declare ClassImpl with public access in Class:



            class Class {
            public:
            Class();
            class ClassImpl;

            private:
            ClassImpl* rep; // should be reference, see note.
            };

            // ...

            using C = Class::ClassImpl;


            Live demo



            You can also make ClassImpl not a nested class.



            Note: you might prefer having Class::rep to be a reference rather than a (naked) pointer. There is no reason for a valid Class instance not to have an implementation object (a null pointer).






            share|improve this answer


























            • The naked pointer was just for the example, I use smart pointers actually

              – Xatyrian
              Jan 2 at 15:12
















            1















            Is there a way to use usingon the private nested class ClassImpl ?




            Yes. Declare ClassImpl with public access in Class:



            class Class {
            public:
            Class();
            class ClassImpl;

            private:
            ClassImpl* rep; // should be reference, see note.
            };

            // ...

            using C = Class::ClassImpl;


            Live demo



            You can also make ClassImpl not a nested class.



            Note: you might prefer having Class::rep to be a reference rather than a (naked) pointer. There is no reason for a valid Class instance not to have an implementation object (a null pointer).






            share|improve this answer


























            • The naked pointer was just for the example, I use smart pointers actually

              – Xatyrian
              Jan 2 at 15:12














            1












            1








            1








            Is there a way to use usingon the private nested class ClassImpl ?




            Yes. Declare ClassImpl with public access in Class:



            class Class {
            public:
            Class();
            class ClassImpl;

            private:
            ClassImpl* rep; // should be reference, see note.
            };

            // ...

            using C = Class::ClassImpl;


            Live demo



            You can also make ClassImpl not a nested class.



            Note: you might prefer having Class::rep to be a reference rather than a (naked) pointer. There is no reason for a valid Class instance not to have an implementation object (a null pointer).






            share|improve this answer
















            Is there a way to use usingon the private nested class ClassImpl ?




            Yes. Declare ClassImpl with public access in Class:



            class Class {
            public:
            Class();
            class ClassImpl;

            private:
            ClassImpl* rep; // should be reference, see note.
            };

            // ...

            using C = Class::ClassImpl;


            Live demo



            You can also make ClassImpl not a nested class.



            Note: you might prefer having Class::rep to be a reference rather than a (naked) pointer. There is no reason for a valid Class instance not to have an implementation object (a null pointer).







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Feb 23 at 10:18

























            answered Jan 2 at 11:50









            YSCYSC

            25k557112




            25k557112













            • The naked pointer was just for the example, I use smart pointers actually

              – Xatyrian
              Jan 2 at 15:12



















            • The naked pointer was just for the example, I use smart pointers actually

              – Xatyrian
              Jan 2 at 15:12

















            The naked pointer was just for the example, I use smart pointers actually

            – Xatyrian
            Jan 2 at 15:12





            The naked pointer was just for the example, I use smart pointers actually

            – Xatyrian
            Jan 2 at 15:12


















            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54005503%2fuse-the-using-directive-on-a-private-nested-class%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            adP bG3d Fsa6I8PdP7
            uJM2E9OExdZZkvJcjzesSb,sKAFLnlw

            Popular posts from this blog

            Monofisismo

            Angular Downloading a file using contenturl with Basic Authentication

            Olmecas