98 ms·
You're definitely not thick! This is getting a bit into the weeds of lower-level C++, but it is useful. So what delete is doing is explicitly saying that a give
by TFortunato 5y ago
You're definitely not thick! This is getting a bit into the weeds of lower-level C++, but it is useful. So what delete is doing is explicitly saying that a given method (with a particular signature) is defined to not exist. It's usually used in cases where the compiler would automatically create a method for you, or use a method you wouldn't want to be used.
The example they give is the reference wrapper, which (as the name might suggest), is used to wrap a reference to some thing. To reiterate, with hopefully a bit more of what is going on.
If the creator of this method had just created a function:
template<class T>
auto cref(const T&) -> std::reference_wrapper<const T>;
Then by C++ overloading rules, you could call this function with either an const ref LValue, or an RValue of type T. (In their example, they used a number). Which for 95% of functions is totally fine, and desired behavior! However, in this case, it would be bad, because remember, we are trying to wrap a reference to some value (e.g. basically a pointer under the hood), so a pointer to some ephemeral value is likely not what we want.
In order to solve this, the creator explicitly adds:
template<class T>
auto cref(const T&&) = delete;
Now, if the user calls cref on an RValue like a number, they will get a nice error message saying that the function has been explicitly deleted. The reason this works is because "const T&&" is the better match for the type of an RValue, compared to "const T&", so this is the overload that the compiler will try to use, rather than the original version above.
Some other reasons to use delete, is if you want to do stuff like explicitly forbid the use of copy constructors, because you have some object that you don't want copies made of for whatever reason. By explicitly deleting the copy constructor, you can be sure that no copies are accidentally made somewhere in user code (which is especially useful when your code interacts with other libraries you don't control)
I hope that made sense, but the TLDR is that there are a lot of ways construct objects, delete objects, to copy / move data around, etc. If you are doing low-level memory management / optimization, you may want to explicitly tell the compiler not to do the normal "helpful" stuff it does for you, such as creating default constructors / overloads, and this is the supported way of doing that in the standard.
- cogman10 5y agoYup that makes a ton of sense, thanks.