Figuring out the constness of an object within its destructor












12














I have a class Stuff, with two functions foo (const and non-const):



class Stuff
{
public:
~Stuff() { foo(); }

void foo() const { cout << "const foo" << endl; }
void foo() { cout << "non-const foo" << endl; }
};


Here's what I am trying to do:




  1. If the stuff was const, call const foo in the destructor of Stuff.


  2. if the stuff wasn't const, call non-const foo in the destructor of Stuff.



I was hoping that just defining the destructor as shown above would work, but it turns out that the constness is stripped away right before executing the destructor (it is enforced right after the constructor completes, so I cannot set any flag there either). To make it clearer, here's an example:



{ Stuff stuff; }
{ const Stuff cstuff; }


This code prints "non-const foo" twice. I want it to print "non-const foo", followed by "const foo". Is that possible with C++?



EDIT: A few people are asking for more context. In the real code, stuff is basically a handle to some data. If stuff is accessed in a non-const manner, I assume that the data has been modified, so I need to communicate that to other processes (MPI) using the foo function (after I am done modifying it -> in the destructor, when I release the handle). If it was accessed in a const-manner, I know I don't need to transfer anything, so I am calling non-const foo, that does nothing.










share|improve this question
























  • The destructor destroys the object, by definition it's not const. Const only applies if you are calling stuff.foo() or cstuff.foo().
    – Matthieu Brucher
    Dec 18 '18 at 20:59






  • 7




    It's not possible to detect whether the object is const in the constructor or destructor. This might be an XY problem.
    – Brian
    Dec 18 '18 at 21:00






  • 1




    It is not const both in the constructor and the destructor. You want to know in the constructor if it will be, and in the destructor if it was. Strange
    – bruno
    Dec 18 '18 at 21:07






  • 2




    As per your edit: It sounds as though you are trying to implement transactional semantics of some kind. Would it perhaps make sense to keep track of whether state was modified using a flag (which only gets set on the mutable code-path), and implementing the conditional behavior in the destructor based on whether this flag was toggled?
    – Bitwize
    Dec 18 '18 at 21:16






  • 5




    It sounds to me like you might want two different types, MutableStuff and ImmutableStuff.
    – molbdnilo
    Dec 18 '18 at 21:16


















12














I have a class Stuff, with two functions foo (const and non-const):



class Stuff
{
public:
~Stuff() { foo(); }

void foo() const { cout << "const foo" << endl; }
void foo() { cout << "non-const foo" << endl; }
};


Here's what I am trying to do:




  1. If the stuff was const, call const foo in the destructor of Stuff.


  2. if the stuff wasn't const, call non-const foo in the destructor of Stuff.



I was hoping that just defining the destructor as shown above would work, but it turns out that the constness is stripped away right before executing the destructor (it is enforced right after the constructor completes, so I cannot set any flag there either). To make it clearer, here's an example:



{ Stuff stuff; }
{ const Stuff cstuff; }


This code prints "non-const foo" twice. I want it to print "non-const foo", followed by "const foo". Is that possible with C++?



EDIT: A few people are asking for more context. In the real code, stuff is basically a handle to some data. If stuff is accessed in a non-const manner, I assume that the data has been modified, so I need to communicate that to other processes (MPI) using the foo function (after I am done modifying it -> in the destructor, when I release the handle). If it was accessed in a const-manner, I know I don't need to transfer anything, so I am calling non-const foo, that does nothing.










share|improve this question
























  • The destructor destroys the object, by definition it's not const. Const only applies if you are calling stuff.foo() or cstuff.foo().
    – Matthieu Brucher
    Dec 18 '18 at 20:59






  • 7




    It's not possible to detect whether the object is const in the constructor or destructor. This might be an XY problem.
    – Brian
    Dec 18 '18 at 21:00






  • 1




    It is not const both in the constructor and the destructor. You want to know in the constructor if it will be, and in the destructor if it was. Strange
    – bruno
    Dec 18 '18 at 21:07






  • 2




    As per your edit: It sounds as though you are trying to implement transactional semantics of some kind. Would it perhaps make sense to keep track of whether state was modified using a flag (which only gets set on the mutable code-path), and implementing the conditional behavior in the destructor based on whether this flag was toggled?
    – Bitwize
    Dec 18 '18 at 21:16






  • 5




    It sounds to me like you might want two different types, MutableStuff and ImmutableStuff.
    – molbdnilo
    Dec 18 '18 at 21:16
















12












12








12







I have a class Stuff, with two functions foo (const and non-const):



class Stuff
{
public:
~Stuff() { foo(); }

void foo() const { cout << "const foo" << endl; }
void foo() { cout << "non-const foo" << endl; }
};


Here's what I am trying to do:




  1. If the stuff was const, call const foo in the destructor of Stuff.


  2. if the stuff wasn't const, call non-const foo in the destructor of Stuff.



I was hoping that just defining the destructor as shown above would work, but it turns out that the constness is stripped away right before executing the destructor (it is enforced right after the constructor completes, so I cannot set any flag there either). To make it clearer, here's an example:



{ Stuff stuff; }
{ const Stuff cstuff; }


This code prints "non-const foo" twice. I want it to print "non-const foo", followed by "const foo". Is that possible with C++?



EDIT: A few people are asking for more context. In the real code, stuff is basically a handle to some data. If stuff is accessed in a non-const manner, I assume that the data has been modified, so I need to communicate that to other processes (MPI) using the foo function (after I am done modifying it -> in the destructor, when I release the handle). If it was accessed in a const-manner, I know I don't need to transfer anything, so I am calling non-const foo, that does nothing.










share|improve this question















I have a class Stuff, with two functions foo (const and non-const):



class Stuff
{
public:
~Stuff() { foo(); }

void foo() const { cout << "const foo" << endl; }
void foo() { cout << "non-const foo" << endl; }
};


Here's what I am trying to do:




  1. If the stuff was const, call const foo in the destructor of Stuff.


  2. if the stuff wasn't const, call non-const foo in the destructor of Stuff.



I was hoping that just defining the destructor as shown above would work, but it turns out that the constness is stripped away right before executing the destructor (it is enforced right after the constructor completes, so I cannot set any flag there either). To make it clearer, here's an example:



{ Stuff stuff; }
{ const Stuff cstuff; }


This code prints "non-const foo" twice. I want it to print "non-const foo", followed by "const foo". Is that possible with C++?



EDIT: A few people are asking for more context. In the real code, stuff is basically a handle to some data. If stuff is accessed in a non-const manner, I assume that the data has been modified, so I need to communicate that to other processes (MPI) using the foo function (after I am done modifying it -> in the destructor, when I release the handle). If it was accessed in a const-manner, I know I don't need to transfer anything, so I am calling non-const foo, that does nothing.







c++ const destructor






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 18 '18 at 21:13

























asked Dec 18 '18 at 20:57









Touloudou

12010




12010












  • The destructor destroys the object, by definition it's not const. Const only applies if you are calling stuff.foo() or cstuff.foo().
    – Matthieu Brucher
    Dec 18 '18 at 20:59






  • 7




    It's not possible to detect whether the object is const in the constructor or destructor. This might be an XY problem.
    – Brian
    Dec 18 '18 at 21:00






  • 1




    It is not const both in the constructor and the destructor. You want to know in the constructor if it will be, and in the destructor if it was. Strange
    – bruno
    Dec 18 '18 at 21:07






  • 2




    As per your edit: It sounds as though you are trying to implement transactional semantics of some kind. Would it perhaps make sense to keep track of whether state was modified using a flag (which only gets set on the mutable code-path), and implementing the conditional behavior in the destructor based on whether this flag was toggled?
    – Bitwize
    Dec 18 '18 at 21:16






  • 5




    It sounds to me like you might want two different types, MutableStuff and ImmutableStuff.
    – molbdnilo
    Dec 18 '18 at 21:16




















  • The destructor destroys the object, by definition it's not const. Const only applies if you are calling stuff.foo() or cstuff.foo().
    – Matthieu Brucher
    Dec 18 '18 at 20:59






  • 7




    It's not possible to detect whether the object is const in the constructor or destructor. This might be an XY problem.
    – Brian
    Dec 18 '18 at 21:00






  • 1




    It is not const both in the constructor and the destructor. You want to know in the constructor if it will be, and in the destructor if it was. Strange
    – bruno
    Dec 18 '18 at 21:07






  • 2




    As per your edit: It sounds as though you are trying to implement transactional semantics of some kind. Would it perhaps make sense to keep track of whether state was modified using a flag (which only gets set on the mutable code-path), and implementing the conditional behavior in the destructor based on whether this flag was toggled?
    – Bitwize
    Dec 18 '18 at 21:16






  • 5




    It sounds to me like you might want two different types, MutableStuff and ImmutableStuff.
    – molbdnilo
    Dec 18 '18 at 21:16


















The destructor destroys the object, by definition it's not const. Const only applies if you are calling stuff.foo() or cstuff.foo().
– Matthieu Brucher
Dec 18 '18 at 20:59




The destructor destroys the object, by definition it's not const. Const only applies if you are calling stuff.foo() or cstuff.foo().
– Matthieu Brucher
Dec 18 '18 at 20:59




7




7




It's not possible to detect whether the object is const in the constructor or destructor. This might be an XY problem.
– Brian
Dec 18 '18 at 21:00




It's not possible to detect whether the object is const in the constructor or destructor. This might be an XY problem.
– Brian
Dec 18 '18 at 21:00




1




1




It is not const both in the constructor and the destructor. You want to know in the constructor if it will be, and in the destructor if it was. Strange
– bruno
Dec 18 '18 at 21:07




It is not const both in the constructor and the destructor. You want to know in the constructor if it will be, and in the destructor if it was. Strange
– bruno
Dec 18 '18 at 21:07




2




2




As per your edit: It sounds as though you are trying to implement transactional semantics of some kind. Would it perhaps make sense to keep track of whether state was modified using a flag (which only gets set on the mutable code-path), and implementing the conditional behavior in the destructor based on whether this flag was toggled?
– Bitwize
Dec 18 '18 at 21:16




As per your edit: It sounds as though you are trying to implement transactional semantics of some kind. Would it perhaps make sense to keep track of whether state was modified using a flag (which only gets set on the mutable code-path), and implementing the conditional behavior in the destructor based on whether this flag was toggled?
– Bitwize
Dec 18 '18 at 21:16




5




5




It sounds to me like you might want two different types, MutableStuff and ImmutableStuff.
– molbdnilo
Dec 18 '18 at 21:16






It sounds to me like you might want two different types, MutableStuff and ImmutableStuff.
– molbdnilo
Dec 18 '18 at 21:16














1 Answer
1






active

oldest

votes


















16















[...] const and volatile
semantics (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (1.8) starts.




12.4/2 [class.dtor] in N4141.



So no, this is not possible.






share|improve this answer





















  • But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
    – Artyer
    Dec 18 '18 at 21:03






  • 1




    @Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
    – Baum mit Augen
    Dec 18 '18 at 21:04










  • And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
    – Dmytro Dadyka
    Dec 18 '18 at 21:04










  • @DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
    – Baum mit Augen
    Dec 18 '18 at 21:05






  • 1




    @DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
    – Baum mit Augen
    Dec 18 '18 at 21:12













Your Answer






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

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

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

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


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53840945%2ffiguring-out-the-constness-of-an-object-within-its-destructor%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









16















[...] const and volatile
semantics (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (1.8) starts.




12.4/2 [class.dtor] in N4141.



So no, this is not possible.






share|improve this answer





















  • But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
    – Artyer
    Dec 18 '18 at 21:03






  • 1




    @Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
    – Baum mit Augen
    Dec 18 '18 at 21:04










  • And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
    – Dmytro Dadyka
    Dec 18 '18 at 21:04










  • @DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
    – Baum mit Augen
    Dec 18 '18 at 21:05






  • 1




    @DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
    – Baum mit Augen
    Dec 18 '18 at 21:12


















16















[...] const and volatile
semantics (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (1.8) starts.




12.4/2 [class.dtor] in N4141.



So no, this is not possible.






share|improve this answer





















  • But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
    – Artyer
    Dec 18 '18 at 21:03






  • 1




    @Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
    – Baum mit Augen
    Dec 18 '18 at 21:04










  • And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
    – Dmytro Dadyka
    Dec 18 '18 at 21:04










  • @DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
    – Baum mit Augen
    Dec 18 '18 at 21:05






  • 1




    @DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
    – Baum mit Augen
    Dec 18 '18 at 21:12
















16












16








16







[...] const and volatile
semantics (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (1.8) starts.




12.4/2 [class.dtor] in N4141.



So no, this is not possible.






share|improve this answer













[...] const and volatile
semantics (7.1.6.1) are not applied on an object under destruction. They stop being in effect when the
destructor for the most derived object (1.8) starts.




12.4/2 [class.dtor] in N4141.



So no, this is not possible.







share|improve this answer












share|improve this answer



share|improve this answer










answered Dec 18 '18 at 21:01









Baum mit Augen

40.2k12115147




40.2k12115147












  • But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
    – Artyer
    Dec 18 '18 at 21:03






  • 1




    @Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
    – Baum mit Augen
    Dec 18 '18 at 21:04










  • And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
    – Dmytro Dadyka
    Dec 18 '18 at 21:04










  • @DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
    – Baum mit Augen
    Dec 18 '18 at 21:05






  • 1




    @DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
    – Baum mit Augen
    Dec 18 '18 at 21:12




















  • But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
    – Artyer
    Dec 18 '18 at 21:03






  • 1




    @Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
    – Baum mit Augen
    Dec 18 '18 at 21:04










  • And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
    – Dmytro Dadyka
    Dec 18 '18 at 21:04










  • @DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
    – Baum mit Augen
    Dec 18 '18 at 21:05






  • 1




    @DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
    – Baum mit Augen
    Dec 18 '18 at 21:12


















But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
– Artyer
Dec 18 '18 at 21:03




But note that you still can call static_cast<const Stuff&>(*this).foo() to call the const versions of functions.
– Artyer
Dec 18 '18 at 21:03




1




1




@Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
– Baum mit Augen
Dec 18 '18 at 21:04




@Artyer But you'd have to know whether or not you want to, which appears to be the core of the question.
– Baum mit Augen
Dec 18 '18 at 21:04












And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
– Dmytro Dadyka
Dec 18 '18 at 21:04




And in other methods? Is it possible to determine the constancy of the created object from inside the class in principle?
– Dmytro Dadyka
Dec 18 '18 at 21:04












@DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
– Baum mit Augen
Dec 18 '18 at 21:05




@DmytroDadyka In normal member functions, you can overload based on constness, as is demonstrated in OP.
– Baum mit Augen
Dec 18 '18 at 21:05




1




1




@DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
– Baum mit Augen
Dec 18 '18 at 21:12






@DmytroDadyka No, constructors have basically the same clause I quoted here, see 12.1/3.
– Baum mit Augen
Dec 18 '18 at 21:12




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


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

But avoid



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

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


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





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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%2f53840945%2ffiguring-out-the-constness-of-an-object-within-its-destructor%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

How do I know what Microsoft account the skydrive app is syncing to?

When does type information flow backwards in C++?

Grease: Live!