Is there a way to make member function NOT callable from constructor?What are the differences between a pointer variable and a reference variable in C++?Can I call a constructor from another constructor (do constructor chaining) in C++?Throwing exceptions from constructorsHow do I call ::std::make_shared on a class with only protected or private constructors?Calling a base member in constructor in multiple inheritance in C++Equality-compare std::weak_ptrClass inheritance: Constructor and member functions of class not recognized by compilerHow does shared_ptr<T> detect that T derives from enable_shared_from_this<T>?enable_shared_from_this derived class methods are undefined referenceDefault move constructor with mutex member

Multi tool use
Multi tool use

What happens when a metallic dragon and a chromatic dragon mate?

What's the difference between repeating elections every few years and repeating a referendum after a few years?

Check if two datetimes are between two others

Re-submission of rejected manuscript without informing co-authors

Can produce flame be used to grapple, or as an unarmed strike, in the right circumstances?

Are white and non-white police officers equally likely to kill black suspects?

What does 'script /dev/null' do?

Deciding between multiple birth names and dates?

Information to fellow intern about hiring?

Shall I use personal or official e-mail account when registering to external websites for work purpose?

Email Account under attack (really) - anything I can do?

COUNT(id) or MAX(id) - which is faster?

Domain expired, GoDaddy holds it and is asking more money

Why airport relocation isn't done gradually?

Is this food a bread or a loaf?

Eliminate empty elements from a list with a specific pattern

What to wear for invited talk in Canada

What do you call something that goes against the spirit of the law, but is legal when interpreting the law to the letter?

Mapping arrows in commutative diagrams

Why did the Germans forbid the possession of pet pigeons in Rostov-on-Don in 1941?

Is a car considered movable or immovable property?

Prime joint compound before latex paint?

Can a planet have a different gravitational pull depending on its location in orbit around its sun?

Is there a familial term for apples and pears?



Is there a way to make member function NOT callable from constructor?


What are the differences between a pointer variable and a reference variable in C++?Can I call a constructor from another constructor (do constructor chaining) in C++?Throwing exceptions from constructorsHow do I call ::std::make_shared on a class with only protected or private constructors?Calling a base member in constructor in multiple inheritance in C++Equality-compare std::weak_ptrClass inheritance: Constructor and member functions of class not recognized by compilerHow does shared_ptr<T> detect that T derives from enable_shared_from_this<T>?enable_shared_from_this derived class methods are undefined referenceDefault move constructor with mutex member






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








12















I have member function (method) which uses



std::enable_shared_from_this::weak_from_this() 


In short: weak_from_this returns weak_ptr to this. One caveat is it can't be used from constructor.
If somebody would use my function from constructor of inherited class, weak_from_this inside it would return expired weak_ptr. I guard against that with assertion checking that it's not expired, but it's a run-time check.



Is there a way to check against it at compile time?










share|improve this question
























  • Note there is a difference in scope between a child class constructor body and the parent class constructor: the latter has been executed completely before you even start initializing the child class's members (if any), let alone enter the child class constructor body.

    – rubenvb
    8 hours ago






  • 1





    Nice question. One way would be to make a dummy class with pure virtual function weak_from_this and inherit yours from it. This will make it a hard compile error.

    – SergeyA
    8 hours ago











  • @SergeyA Why didn't you post that as an answer? All other people here seem to conclude that it's not possible so either your comment is wrong and misleading or they are wrong and you should show how it can be achieved.

    – Bakuriu
    1 hour ago

















12















I have member function (method) which uses



std::enable_shared_from_this::weak_from_this() 


In short: weak_from_this returns weak_ptr to this. One caveat is it can't be used from constructor.
If somebody would use my function from constructor of inherited class, weak_from_this inside it would return expired weak_ptr. I guard against that with assertion checking that it's not expired, but it's a run-time check.



Is there a way to check against it at compile time?










share|improve this question
























  • Note there is a difference in scope between a child class constructor body and the parent class constructor: the latter has been executed completely before you even start initializing the child class's members (if any), let alone enter the child class constructor body.

    – rubenvb
    8 hours ago






  • 1





    Nice question. One way would be to make a dummy class with pure virtual function weak_from_this and inherit yours from it. This will make it a hard compile error.

    – SergeyA
    8 hours ago











  • @SergeyA Why didn't you post that as an answer? All other people here seem to conclude that it's not possible so either your comment is wrong and misleading or they are wrong and you should show how it can be achieved.

    – Bakuriu
    1 hour ago













12












12








12


2






I have member function (method) which uses



std::enable_shared_from_this::weak_from_this() 


In short: weak_from_this returns weak_ptr to this. One caveat is it can't be used from constructor.
If somebody would use my function from constructor of inherited class, weak_from_this inside it would return expired weak_ptr. I guard against that with assertion checking that it's not expired, but it's a run-time check.



Is there a way to check against it at compile time?










share|improve this question
















I have member function (method) which uses



std::enable_shared_from_this::weak_from_this() 


In short: weak_from_this returns weak_ptr to this. One caveat is it can't be used from constructor.
If somebody would use my function from constructor of inherited class, weak_from_this inside it would return expired weak_ptr. I guard against that with assertion checking that it's not expired, but it's a run-time check.



Is there a way to check against it at compile time?







c++ c++17 shared-ptr weak-ptr






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 8 hours ago









armitus

524114




524114










asked 8 hours ago









KorriKorri

34128




34128












  • Note there is a difference in scope between a child class constructor body and the parent class constructor: the latter has been executed completely before you even start initializing the child class's members (if any), let alone enter the child class constructor body.

    – rubenvb
    8 hours ago






  • 1





    Nice question. One way would be to make a dummy class with pure virtual function weak_from_this and inherit yours from it. This will make it a hard compile error.

    – SergeyA
    8 hours ago











  • @SergeyA Why didn't you post that as an answer? All other people here seem to conclude that it's not possible so either your comment is wrong and misleading or they are wrong and you should show how it can be achieved.

    – Bakuriu
    1 hour ago

















  • Note there is a difference in scope between a child class constructor body and the parent class constructor: the latter has been executed completely before you even start initializing the child class's members (if any), let alone enter the child class constructor body.

    – rubenvb
    8 hours ago






  • 1





    Nice question. One way would be to make a dummy class with pure virtual function weak_from_this and inherit yours from it. This will make it a hard compile error.

    – SergeyA
    8 hours ago











  • @SergeyA Why didn't you post that as an answer? All other people here seem to conclude that it's not possible so either your comment is wrong and misleading or they are wrong and you should show how it can be achieved.

    – Bakuriu
    1 hour ago
















Note there is a difference in scope between a child class constructor body and the parent class constructor: the latter has been executed completely before you even start initializing the child class's members (if any), let alone enter the child class constructor body.

– rubenvb
8 hours ago





Note there is a difference in scope between a child class constructor body and the parent class constructor: the latter has been executed completely before you even start initializing the child class's members (if any), let alone enter the child class constructor body.

– rubenvb
8 hours ago




1




1





Nice question. One way would be to make a dummy class with pure virtual function weak_from_this and inherit yours from it. This will make it a hard compile error.

– SergeyA
8 hours ago





Nice question. One way would be to make a dummy class with pure virtual function weak_from_this and inherit yours from it. This will make it a hard compile error.

– SergeyA
8 hours ago













@SergeyA Why didn't you post that as an answer? All other people here seem to conclude that it's not possible so either your comment is wrong and misleading or they are wrong and you should show how it can be achieved.

– Bakuriu
1 hour ago





@SergeyA Why didn't you post that as an answer? All other people here seem to conclude that it's not possible so either your comment is wrong and misleading or they are wrong and you should show how it can be achieved.

– Bakuriu
1 hour ago












3 Answers
3






active

oldest

votes


















10














I am afraid the answer is "no, it's not possible to protect against this at compile-time." It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for weak_from_this and shared_from_this in the standard library itself.






share|improve this answer






























    4














    No there is no way. Consider:



    void call_me(struct widget*);

    struct widget : std::enable_shared_from_this<widget>
    widget()
    call_me(this);


    void display()
    shared_from_this();

    ;

    // later:

    void call_me(widget* w)
    w->display(); // crash



    The thing is there is a reason you want to check for not calling shared_from_this in the constructor. Think about that reason. It's not that shared_from_this cannot be called, it's because it's return value has no way of being assigned yet. It is also not because it will never be assigned. It's because it will be assigned later in the execution of the code. Order of operation is a runtime property of your program. You cannot assert at compile time for order of operation, which is done at runtime.






    share|improve this answer






























      4














      Not as such, but - if performance is not an issue, you could add a flag which indicates construction is complete, and use that to fail at run-time with such calls:



      class A 

      // ... whatever ...

      A()
      // do construction work
      constructed = true;


      foo()
      if (not constructed)
      throw std::logic_error("Cannot call foo() during construction");

      // the rest of foo


      bool constructed false ;



      You could also make these checks only apply when compiling in DEBUG mode (e.g. with conditional compilation using the preprocessor - #ifndef NDEBUG) so that at run time you won't get the performance penalty. Mind the noexcepts though.



      An alternative to throwing could be assert()'ing.






      share|improve this answer























      • Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

        – Korri
        5 hours ago











      • @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

        – Jesper Juhl
        4 hours ago












      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%2f55576192%2fis-there-a-way-to-make-member-function-not-callable-from-constructor%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      10














      I am afraid the answer is "no, it's not possible to protect against this at compile-time." It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for weak_from_this and shared_from_this in the standard library itself.






      share|improve this answer



























        10














        I am afraid the answer is "no, it's not possible to protect against this at compile-time." It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for weak_from_this and shared_from_this in the standard library itself.






        share|improve this answer

























          10












          10








          10







          I am afraid the answer is "no, it's not possible to protect against this at compile-time." It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for weak_from_this and shared_from_this in the standard library itself.






          share|improve this answer













          I am afraid the answer is "no, it's not possible to protect against this at compile-time." It's always difficult to prove a negative, but consider this: if it was possible to protect a function this way, it would probably have been done for weak_from_this and shared_from_this in the standard library itself.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 8 hours ago









          AngewAngew

          135k11260354




          135k11260354























              4














              No there is no way. Consider:



              void call_me(struct widget*);

              struct widget : std::enable_shared_from_this<widget>
              widget()
              call_me(this);


              void display()
              shared_from_this();

              ;

              // later:

              void call_me(widget* w)
              w->display(); // crash



              The thing is there is a reason you want to check for not calling shared_from_this in the constructor. Think about that reason. It's not that shared_from_this cannot be called, it's because it's return value has no way of being assigned yet. It is also not because it will never be assigned. It's because it will be assigned later in the execution of the code. Order of operation is a runtime property of your program. You cannot assert at compile time for order of operation, which is done at runtime.






              share|improve this answer



























                4














                No there is no way. Consider:



                void call_me(struct widget*);

                struct widget : std::enable_shared_from_this<widget>
                widget()
                call_me(this);


                void display()
                shared_from_this();

                ;

                // later:

                void call_me(widget* w)
                w->display(); // crash



                The thing is there is a reason you want to check for not calling shared_from_this in the constructor. Think about that reason. It's not that shared_from_this cannot be called, it's because it's return value has no way of being assigned yet. It is also not because it will never be assigned. It's because it will be assigned later in the execution of the code. Order of operation is a runtime property of your program. You cannot assert at compile time for order of operation, which is done at runtime.






                share|improve this answer

























                  4












                  4








                  4







                  No there is no way. Consider:



                  void call_me(struct widget*);

                  struct widget : std::enable_shared_from_this<widget>
                  widget()
                  call_me(this);


                  void display()
                  shared_from_this();

                  ;

                  // later:

                  void call_me(widget* w)
                  w->display(); // crash



                  The thing is there is a reason you want to check for not calling shared_from_this in the constructor. Think about that reason. It's not that shared_from_this cannot be called, it's because it's return value has no way of being assigned yet. It is also not because it will never be assigned. It's because it will be assigned later in the execution of the code. Order of operation is a runtime property of your program. You cannot assert at compile time for order of operation, which is done at runtime.






                  share|improve this answer













                  No there is no way. Consider:



                  void call_me(struct widget*);

                  struct widget : std::enable_shared_from_this<widget>
                  widget()
                  call_me(this);


                  void display()
                  shared_from_this();

                  ;

                  // later:

                  void call_me(widget* w)
                  w->display(); // crash



                  The thing is there is a reason you want to check for not calling shared_from_this in the constructor. Think about that reason. It's not that shared_from_this cannot be called, it's because it's return value has no way of being assigned yet. It is also not because it will never be assigned. It's because it will be assigned later in the execution of the code. Order of operation is a runtime property of your program. You cannot assert at compile time for order of operation, which is done at runtime.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 7 hours ago









                  Guillaume RacicotGuillaume Racicot

                  16.3k53872




                  16.3k53872





















                      4














                      Not as such, but - if performance is not an issue, you could add a flag which indicates construction is complete, and use that to fail at run-time with such calls:



                      class A 

                      // ... whatever ...

                      A()
                      // do construction work
                      constructed = true;


                      foo()
                      if (not constructed)
                      throw std::logic_error("Cannot call foo() during construction");

                      // the rest of foo


                      bool constructed false ;



                      You could also make these checks only apply when compiling in DEBUG mode (e.g. with conditional compilation using the preprocessor - #ifndef NDEBUG) so that at run time you won't get the performance penalty. Mind the noexcepts though.



                      An alternative to throwing could be assert()'ing.






                      share|improve this answer























                      • Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

                        – Korri
                        5 hours ago











                      • @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

                        – Jesper Juhl
                        4 hours ago
















                      4














                      Not as such, but - if performance is not an issue, you could add a flag which indicates construction is complete, and use that to fail at run-time with such calls:



                      class A 

                      // ... whatever ...

                      A()
                      // do construction work
                      constructed = true;


                      foo()
                      if (not constructed)
                      throw std::logic_error("Cannot call foo() during construction");

                      // the rest of foo


                      bool constructed false ;



                      You could also make these checks only apply when compiling in DEBUG mode (e.g. with conditional compilation using the preprocessor - #ifndef NDEBUG) so that at run time you won't get the performance penalty. Mind the noexcepts though.



                      An alternative to throwing could be assert()'ing.






                      share|improve this answer























                      • Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

                        – Korri
                        5 hours ago











                      • @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

                        – Jesper Juhl
                        4 hours ago














                      4












                      4








                      4







                      Not as such, but - if performance is not an issue, you could add a flag which indicates construction is complete, and use that to fail at run-time with such calls:



                      class A 

                      // ... whatever ...

                      A()
                      // do construction work
                      constructed = true;


                      foo()
                      if (not constructed)
                      throw std::logic_error("Cannot call foo() during construction");

                      // the rest of foo


                      bool constructed false ;



                      You could also make these checks only apply when compiling in DEBUG mode (e.g. with conditional compilation using the preprocessor - #ifndef NDEBUG) so that at run time you won't get the performance penalty. Mind the noexcepts though.



                      An alternative to throwing could be assert()'ing.






                      share|improve this answer













                      Not as such, but - if performance is not an issue, you could add a flag which indicates construction is complete, and use that to fail at run-time with such calls:



                      class A 

                      // ... whatever ...

                      A()
                      // do construction work
                      constructed = true;


                      foo()
                      if (not constructed)
                      throw std::logic_error("Cannot call foo() during construction");

                      // the rest of foo


                      bool constructed false ;



                      You could also make these checks only apply when compiling in DEBUG mode (e.g. with conditional compilation using the preprocessor - #ifndef NDEBUG) so that at run time you won't get the performance penalty. Mind the noexcepts though.



                      An alternative to throwing could be assert()'ing.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered 6 hours ago









                      einpoklumeinpoklum

                      37k28132263




                      37k28132263












                      • Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

                        – Korri
                        5 hours ago











                      • @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

                        – Jesper Juhl
                        4 hours ago


















                      • Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

                        – Korri
                        5 hours ago











                      • @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

                        – Jesper Juhl
                        4 hours ago

















                      Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

                      – Korri
                      5 hours ago





                      Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go with assert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.

                      – Korri
                      5 hours ago













                      @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

                      – Jesper Juhl
                      4 hours ago






                      @Korri remember that asserts are usually compiled out in release builds, so nothing will happen. An exception however is not, so it would still terminate the program (if not caught and swallowed) in a release build. You could do both; first assert then throw, or just throw.

                      – Jesper Juhl
                      4 hours ago


















                      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%2f55576192%2fis-there-a-way-to-make-member-function-not-callable-from-constructor%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







                      iEz3RMjEdd
                      0adKjO D j8x vph8YpupU,CdxMAQhg9N2f,DWhDz3,z7Y C8OuaRw0zb cYd6

                      Popular posts from this blog

                      What is the result of assigning to std::vector::begin()? The Next CEO of Stack OverflowWhat are the differences between a pointer variable and a reference variable in C++?What does the explicit keyword mean?Concatenating two std::vectorsHow to find out if an item is present in a std::vector?Why is “using namespace std” considered bad practice?What is the “-->” operator in C++?What is the easiest way to initialize a std::vector with hardcoded elements?What is The Rule of Three?What are the basic rules and idioms for operator overloading?Why are std::begin and std::end “not memory safe”?

                      Creating centerline of river in QGIS? The 2019 Stack Overflow Developer Survey Results Are In Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)Finding centrelines from polygons in QGIS?Splitting line into two lines with GRASS GIS?Centroid of the equator and a pointpostgis: problems creating flow direction polyline; not all needed connections are drawnhow to make decent sense from scattered river depth measurementsQGIS Interpolation on Curved Grid (River DEMs)How to create automatic parking baysShortest path creation between two linesclipping layer using query builder in QGISFinding which side of closest polyline point lies on in QGIS?Create centerline from multi-digitized roadway lines Qgis 2.18Getting bathymetric contours confined only within river banks using QGIS?

                      SQL Server 2016 - excessive memory grant warning on poor performing query The Next CEO of Stack OverflowFix for slow SQL_INLINE_TABLE_VALUED_FUNCTIONLarge memory grant requestsPoor performing Query -Tsql execution plan - estimated number of rows =1 Paste the PlanMSSQL - Query had to wait for memory grantRow estimates always too lowBad performance using “NOT IN”Warning about memory “Excessive Grant” in the query plan - how to find out what is causing it?Optimizing table valued function SQL ServerWhen does SQL Server warn about an Excessive Memory Grant?Warning in Execution Plan