4 ms·
It's never been necessary to use delete to make a class uncopyable. It was always possible by just declaring (but not defining) a private copy constructor/assig
by dataflow 5y ago
It's never been necessary to use delete to make a class uncopyable. It was always possible by just declaring (but not defining) a private copy constructor/assignment. I'd still do the same thing honestly, it's fewer keystrokes and not pointlessly backwards-incompatible.
Better yet, for the majority of cases, just inherit from an uncopyable class like boost::noncopyable.
- kllrnohj 5y agoIf you declare but don't define a private copy constructor/assignment then you hit vague linker errors elsewhere that will likely send a user on a chase trying to figure out how their include paths don't match their linker paths and which library they forgot to link against. '= delete' makes it exceedingly clear that what they are doing is not allowed, rather than "oh god dammit cmake what did I miss now..." Since '= deleted' was added in C++11, there's really not any good "backwards-incompatible" arguments to be made about avoiding it. C++11 support is extremely broad at this point and has been for many, many years now.
- dataflow 5y ago> If you declare but don't define a private copy constructor/assignment then you hit vague linker errors elsewhere that will likely send a user on a chase trying to figure out how their include paths don't match their linker paths and which library they forgot to link against. I think you missed the importance of private. Users of it won't get it to compile for them to get a linker error.
- jcranmer 5y agoA private copy constructor can still be copied in the class itself. If you omit the definition, you still get a linker error message, but linker errors are among the most obtuse to actually discover. (Where did the copy construction actually happen? Who knows! You get, at best, the function that called it). A deleted copy constructor produces better error messages. And it's not really backwards-incompatible at this point--deleted functions exist in compiler versions old enough to get a COVID-19 vaccine.
- metiscus 5y agoAnother worry is that an engineer will see the link error and "fix it" instead of getting why it was done and diagnosing the misuse of the class.
- dataflow 5y agoI suppose this is possible for people who never programmed C++ before C++11, I haven't really encountered this incident to know. The biggest annoyance I've encountered isn't a bug - rather, it's the annoying IDE warning that the member is unimplemented!
- dataflow 5y agoIn theory yeah, in practice it's incredibly rare for a class to look like it should be copyable to its own maintainer AND for the maintainer to try to copy it from its own methods AND for a linker error to be obscure for them to figure out when they do their first debug build. In fact I'm not sure I've ever encountered this situation. Usually it's pretty obvious if your class should be copyable or not from the outset so it's not common to make the mistake to begin with.
- gpderetta 5y ago> not pointlessly backwards-incompatible. if the only reason for using the C++11 standard were the =delete syntax, by all means, just use boost::noncopyable. But if you are using features from C++11, then there is really no reason for not using the new syntax.
- Taywee 5y agoMy original post: Private constructors still match for overload resolution, and can cause your compiler to barf when a explicit deletion would allow the compiler to find an appropriate legal match. I was wrong. delete leaves it in the overload set. I've been using C++ for a decade and I'm still tripping over some of the stupider semantics.
- quietbritishjim 5y agoYou edited before I got the chance to make a snarky reply :-) For the record, the following snippet will not compile because the deleted constructor will be matched during overload resolution. class C { public: C(int) = delete; C(long) {} }; int main() { C x(3); }