Is there a way to make member function NOT callable from constructor?What are the differences between a...
Shall I use personal or official e-mail account when registering to external websites for work purpose?
My colleague's body is amazing
How is it possible for user's password to be changed after storage was encrypted? (on OS X, Android)
Can a planet have a different gravitational pull depending on its location in orbit around its sun?
I am not able to install anything in ubuntu
Why is making salt water prohibited on Shabbat?
Why is my log file so massive? 22gb. I am running log backups
I see my dog run
"listening to me about as much as you're listening to this pole here"
How to move the player while also allowing forces to affect it
How to manage monthly salary
Finding files for which a command fails
Is there a way to make member function NOT callable from constructor?
Symmetry in quantum mechanics
Check if two datetimes are between two others
Could a US political party gain complete control over the government by removing checks & balances?
How to make payment on the internet without leaving a money trail?
Why do we use polarized capacitors?
New order #4: World
Is every set a filtered colimit of finite sets?
LM317 - Calculate dissipation due to voltage drop
Wild Shape Centaur Into a Giant Elk: do their Charges stack?
Need help identifying/translating a plaque in Tangier, Morocco
Are white and non-white police officers equally likely to kill black suspects?
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;
}
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
add a comment |
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
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
3 hours ago
1
Nice question. One way would be to make a dummy class with pure virtual functionweak_from_thisand inherit yours from it. This will make it a hard compile error.
– SergeyA
3 hours ago
add a comment |
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
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
c++ c++17 shared-ptr weak-ptr
edited 3 hours ago
armitus
509114
509114
asked 3 hours ago
KorriKorri
32627
32627
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
3 hours ago
1
Nice question. One way would be to make a dummy class with pure virtual functionweak_from_thisand inherit yours from it. This will make it a hard compile error.
– SergeyA
3 hours ago
add a comment |
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
3 hours ago
1
Nice question. One way would be to make a dummy class with pure virtual functionweak_from_thisand inherit yours from it. This will make it a hard compile error.
– SergeyA
3 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
3 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
3 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
3 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
3 hours ago
add a comment |
3 Answers
3
active
oldest
votes
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.
add a comment |
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.
add a comment |
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.
Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go withassert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.
– Korri
1 hour ago
@Korri remember thatasserts 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; firstassertthenthrow, or justthrow.
– Jesper Juhl
9 mins ago
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered 3 hours ago
AngewAngew
134k11260353
134k11260353
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 3 hours ago
Guillaume RacicotGuillaume Racicot
16.3k53872
16.3k53872
add a comment |
add a comment |
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.
Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go withassert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.
– Korri
1 hour ago
@Korri remember thatasserts 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; firstassertthenthrow, or justthrow.
– Jesper Juhl
9 mins ago
add a comment |
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.
Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go withassert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.
– Korri
1 hour ago
@Korri remember thatasserts 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; firstassertthenthrow, or justthrow.
– Jesper Juhl
9 mins ago
add a comment |
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.
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.
answered 1 hour ago
einpoklumeinpoklum
37k28132263
37k28132263
Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go withassert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.
– Korri
1 hour ago
@Korri remember thatasserts 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; firstassertthenthrow, or justthrow.
– Jesper Juhl
9 mins ago
add a comment |
Since apparently there isn't compile-time solution which doesn't make code less readable, I decided to go withassert(!wptr.expired()). I think it's a little bit more fitting than exception, because there is no way to recover from this situation.
– Korri
1 hour ago
@Korri remember thatasserts 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; firstassertthenthrow, or justthrow.
– Jesper Juhl
9 mins 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
1 hour 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
1 hour 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
9 mins 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
9 mins ago
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
3 hours ago
1
Nice question. One way would be to make a dummy class with pure virtual function
weak_from_thisand inherit yours from it. This will make it a hard compile error.– SergeyA
3 hours ago