boostorg / core

Boost Core Utilities
132 stars 87 forks source link

Inheriting from boost::noncopyable also implies deleted move operations #70

Closed mbamelis closed 4 years ago

mbamelis commented 4 years ago

Hi

In my code, I inherit from boost::noncopyable to remove the defaulted copy operations based on the properties of a template parameter. However, I noticed this also makes the defaulted move operations of my class implicitly deleted. This is due to boost::noncopyable not explicitly defining its move operations, and as a result, they are implicitly deleted. And my class inherits this.

Is this intended or should boost::noncopyable explicitly mark its move operations as default?

pdimov commented 4 years ago

If we mark move operations as default, won't this be a breaking change for people who rely on the current behavior? Their classes will unexpectedly acquire move constructors, which quite probably will be broken.

Lastique commented 4 years ago

IMHO, we should just mark noncopyable deprecated and eventually remove it. It is no longer relevant in C++11 and later era and it encourages bad programming practices.

mbamelis commented 4 years ago

It avoids boilerplate because SFINAE tricks with std::enable_if cannot be applied on special member functions. With the introduction of requires clauses in C++20, special member functions can be made conditionally available more easily and intuitively.

And indeed, many classes may in some way rely on noncopyable also removing the move operations. Changing that behavior could be detrimental... and I actually had not considered that.

Thanks for the input.

Lastique commented 4 years ago

SFINAE tricks with std::enable_if cannot be applied on special member functions.

Just for completeness, (a) they can and (b) they are not needed to prohibit copyability.