Consider the following code:
#include<utility>
struct S {
void f(int) = delete;
void f(int) && { }
};
int main() { }
It doesn't compile saying that the member method cannot be overloaded and it makes sense, of course.
On the other side, the following code compiles:
#include<utility>
struct S {
void f(int) & = delete;
void f(int) && { }
};
int main() {
S s;
// s.f(42); <-- error, deleted member method
std::move(s).f(42);
}
Is that legal code?
Wouldn't it be possible to define two completely different interfaces within the same class, the former to be used with lvalues, the latter with rvalues?
Apart from the fact that it doesn't make much sense, but it really hurts me.
Shouldn't a deleted function be deleted as a whole, instead of deleted only if you are a lvalue?
Which is the purpose of this feature? Is it the classic obscure corner case or is there something more I can't see?
Sometimes it makes sense to prohibit certain operations if object is l- or r-value.
Imagine RAII wrapper for FILE*
. It opens file in constructor, closes it in destructor, turning C feature requiring manual control to C++ exception-safe class. To interact with C interface, there is a .get()
member which returns raw pointer. Someone might write:
FILE* file = CFile("file.txt").get();
It would compile, but it is wrong: file would be closed as soon, as file
variable would be initialized. If you delete an r-value overload (on never provide it in the first place), then it would lead to compile-time error and save us from bug-hunting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With