Is there a way to make member function NOT callable from constructor? The 2019 Stack Overflow...

Where to refill my bottle in India?

What do the Banks children have against barley water?

Does a dangling wire really electrocute me if I'm standing in water?

What is the purpose of the constant in the probability density function

Idiomatic way to prevent slicing?

Why could you hear an Amstrad CPC working?

Is it possible for the two major parties in the UK to form a coalition with each other instead of a much smaller party?

Does it makes sense to buy a new cycle to learn riding?

Is this food a bread or a loaf?

aging parents with no investments

Why is the maximum length of OpenWrt’s root password 8 characters?

"What time...?" or "At what time...?" - what is more grammatically correct?

How come people say “Would of”?

How long do I have to send payment?

What is the use of option -o in the useradd command?

Is three citations per paragraph excessive for undergraduate research paper?

Where does the "burst of radiance" from Holy Weapon originate?

Is there a name of the flying bionic bird?

Can distinct morphisms between curves induce the same morphism on singular cohomology?

What is the best strategy for white in this position?

"To split hairs" vs "To be pedantic"

Inflated grade on resume at previous job, might former employer tell new employer?

Should I use my personal or workplace e-mail when registering to external websites for work purpose?

Which Sci-Fi work first showed weapon of galactic-scale mass destruction?



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



The 2019 Stack Overflow Developer Survey Results Are InWhat 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;
}







18















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
    yesterday






  • 4





    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
    yesterday






  • 5





    @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
    yesterday











  • @Bakuriu well, I did not have the energy to polish it to the full blown answer. It is possible that it is not a workable solution.

    – SergeyA
    13 hours ago


















18















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
    yesterday






  • 4





    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
    yesterday






  • 5





    @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
    yesterday











  • @Bakuriu well, I did not have the energy to polish it to the full blown answer. It is possible that it is not a workable solution.

    – SergeyA
    13 hours ago














18












18








18


3






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 yesterday









armitus

524114




524114










asked yesterday









KorriKorri

37129




37129













  • 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
    yesterday






  • 4





    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
    yesterday






  • 5





    @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
    yesterday











  • @Bakuriu well, I did not have the energy to polish it to the full blown answer. It is possible that it is not a workable solution.

    – SergeyA
    13 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
    yesterday






  • 4





    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
    yesterday






  • 5





    @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
    yesterday











  • @Bakuriu well, I did not have the energy to polish it to the full blown answer. It is possible that it is not a workable solution.

    – SergeyA
    13 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
yesterday





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
yesterday




4




4





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
yesterday





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
yesterday




5




5





@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
yesterday





@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
yesterday













@Bakuriu well, I did not have the energy to polish it to the full blown answer. It is possible that it is not a workable solution.

– SergeyA
13 hours ago





@Bakuriu well, I did not have the energy to polish it to the full blown answer. It is possible that it is not a workable solution.

– SergeyA
13 hours ago












3 Answers
3






active

oldest

votes


















15














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 ...
      public:
      A() {
      // do construction work
      constructed = true;
      }

      foo() {
      if (not constructed) {
      throw std::logic_error("Cannot call foo() during construction");
      }
      // the rest of foo
      }

      protected:
      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
        yesterday











      • @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
        yesterday














      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









      15














      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




























        15














        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


























          15












          15








          15







          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 yesterday









          AngewAngew

          135k11261354




          135k11261354

























              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 yesterday









                  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 ...
                      public:
                      A() {
                      // do construction work
                      constructed = true;
                      }

                      foo() {
                      if (not constructed) {
                      throw std::logic_error("Cannot call foo() during construction");
                      }
                      // the rest of foo
                      }

                      protected:
                      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
                        yesterday











                      • @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
                        yesterday


















                      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 ...
                      public:
                      A() {
                      // do construction work
                      constructed = true;
                      }

                      foo() {
                      if (not constructed) {
                      throw std::logic_error("Cannot call foo() during construction");
                      }
                      // the rest of foo
                      }

                      protected:
                      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
                        yesterday











                      • @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
                        yesterday
















                      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 ...
                      public:
                      A() {
                      // do construction work
                      constructed = true;
                      }

                      foo() {
                      if (not constructed) {
                      throw std::logic_error("Cannot call foo() during construction");
                      }
                      // the rest of foo
                      }

                      protected:
                      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 ...
                      public:
                      A() {
                      // do construction work
                      constructed = true;
                      }

                      foo() {
                      if (not constructed) {
                      throw std::logic_error("Cannot call foo() during construction");
                      }
                      // the rest of foo
                      }

                      protected:
                      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








                      edited 20 hours ago

























                      answered yesterday









                      einpoklumeinpoklum

                      37.1k28132263




                      37.1k28132263













                      • 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
                        yesterday











                      • @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
                        yesterday





















                      • 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
                        yesterday











                      • @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
                        yesterday



















                      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
                      yesterday





                      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
                      yesterday













                      @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
                      yesterday







                      @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
                      yesterday




















                      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







                      Popular posts from this blog

                      Taj Mahal Inhaltsverzeichnis Aufbau | Geschichte | 350-Jahr-Feier | Heutige Bedeutung | Siehe auch |...

                      Baia Sprie Cuprins Etimologie | Istorie | Demografie | Politică și administrație | Arii naturale...

                      Ciclooctatetraenă Vezi și | Bibliografie | Meniu de navigare637866text4148569-500570979m