sumit_tuwien Posted June 13, 2018 Report Share Posted June 13, 2018 Hello All, I found out this issue while I was playing with some SystemC stuffs (During meta-programming). This is a C++ question which I separated out from the SystemC implementation. I could have gone to pure C++ forum but since I use this forum, I believe if I ask here people will be benefited more. I observed that if I explicitly delete only constructor and destructor of a class then the resultant implementation deletes copy constructor & move constructor, but the compiler still makes copy assignment and move assignment operators implicitly available! Which in turn makes assignment possible! My question is what is the rational of this? What is the use case where this can be used. Following is an example code for reference: # ifndef MOEGLICH_H_ # define MOEGLICH_H_ # include <cstdint> class Moeglich final { public : explicit Moeglich() = delete ; ~Moeglich() = delete ; /* // With explicit deletion Moeglich& operator=(const Moeglich& other) = delete ; Moeglich(const Moeglich& other) = delete ; Moeglich&& operator=(Moeglich&& other) = delete ; Moeglich(Moeglich&& other) = delete ; */ static constexpr uint16_t Egal(const uint8_t& var_) noexcept { return static_cast< uint16_t > ( var_ ) ; } }; # endif # include <cstdlib> # include <iostream> # include <type_traits> int main(int argc, char* argv[]) { std::cout << std::boolalpha << "Is constructible : " << std::is_constructible<Moeglich>::value << std::endl << "Is destructible : " << std::is_destructible<Moeglich>::value << std::endl << "Is copy constructible : " << std::is_copy_constructible<Moeglich>::value << std::endl << "Is move constructible : " << std::is_move_constructible<Moeglich>::value << std::endl << "Is copy assignable : " << std::is_copy_assignable<Moeglich>::value << std::endl << "Is move assignable : " << std::is_move_assignable<Moeglich>::value << std::endl << "Is assignable : " << std::is_assignable<Moeglich, Moeglich>::value << std::endl ; /* Following were what I wanted to bar anyway : const Moeglich mom {} ; Moeglich pop {} ; Moeglich foo {} ; foo = mom ; foo = std::move(pop) ; */ return EXIT_SUCCESS ; } Regards, Sumit Quote Link to comment Share on other sites More sharing options...
David Black Posted June 13, 2018 Report Share Posted June 13, 2018 A derived class could inherit this. Quote Link to comment Share on other sites More sharing options...
sumit_tuwien Posted June 13, 2018 Author Report Share Posted June 13, 2018 3 minutes ago, David Black said: A derived class could inherit this. Hello David, Yes, but please note that I already applied final keyword at the end of the class and hence this class cannot be derived from. Regards, Sumit Quote Link to comment Share on other sites More sharing options...
Eyck Posted June 13, 2018 Report Share Posted June 13, 2018 Hi Sumit, Quoting http://en.cppreference.com: Some member functions are special: under certain circumstances they are defined by the compiler even if not defined by the user. They are: Default constructor Copy constructor Move constructor (since C++11) Copy assignment operator Move assignment operator (since C++11) Destructor So in the code you show you just delete the default constructor and the destructor. Obviously this does not make sense as you cannot construct any object since you do not have a parameterized constructor. But if you have one this declaration makes sense: the user of this class cannot create a default object, he has to provide some parameters. Deleting the destructor prohibits the creation of an object on the stack, you can only create them on the heap (and never release the memory except you use placement new on a pre-allocated area). But the the standard comittee has a special section on this in the C++ core Guidelines: C.21: If you define or =delete any default operation, define or =delete them all BTW, if you inherit from a class having a deleted destructor the destructor of the child is also deleted HTH -Eyck sumit_tuwien 1 Quote Link to comment Share on other sites More sharing options...
sumit_tuwien Posted June 13, 2018 Author Report Share Posted June 13, 2018 Hello Eyck, Quote But the the standard comittee has a special section on this in the C++ core Guidelines: C.21: If you define or =delete any default operation, define or =delete them all This is an amazing pointer. I see I have created a lot of confusions by vaguely putting some code and not mentioning the intent. I will never construct this object. All I am interested is accessing const uint8_t duh { 5 } ; const uint16_t notEgal { Moeglich::Egal(duh) } ; Here is what is important for me: Sometimes, I need partial template specialization of functions which is not allowed which can be enabled if I put this function inside a template class. Your link, very clearly lays down the rule. My expectation from the compiler was wrong and my use-case cannot be understood in a special way by the compiler. Meanwhile, I also asked help from stackoverflow.com in here (I generally do not do that, because they are champions in downvoting questions). You can see how many confusing and different answers from people. Please note:: Since I always explicitly mention all 6 special member functions, it was fine. This was accidentally found when in one place I missed 4 of them and started wondering. Glad that I did that mistake, which enabled me to learn something and correct some mistakes in my understanding. Thanks for the great help. Regards, Sumit Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.