Why delete a non-member function? [duplicate]
Asked Answered
P

1

8

This is about non-member functions. I do understand this as an implementation. But I have a bit of puzzlement with the logic behind?

     // why this?
     void do_not_use_this_ever ( void ) = delete ;

If I do not want a function to be used, why declare it and then delete it? Why not just:

     // why not this?
     // void do_not_use_this_ever ( void ) = delete ;

If = delete declares an intent, just a comment like above declares the same intent.

Can anyone think of a use-case where declaring a non-member function as deleted is better then not have it at all?

Update

Already answered here . Although. Both answers use std::cref as an example. As @geza said in the comment to his answer, it would be rather beneficial to discuss other use cases as well.

Pryce answered 4/8, 2018 at 6:46 Comment(5)
A deleted function still is considered in overload resolution, which can be useful for disallowing certain overloads but not others. Maybe not for functions taking no arguments, but if arguments are taken, or for templated functions, this is really useful.Gastrovascular
A non-member function in general, or a non-member function with a void parameter list?Upstretched
Possibly to disable template functions for certain argument typesKlepht
@PiotrSkotnicki exactly. not just std::cref. A non-member function in general. Template or not. That's not discussed in any answer, AFAIK.Pryce
@ChefGladiator exactly what? I gave two optionsUpstretched
G
5

Deleting a non-member function can be useful to disable a function with certain parameters. For example, here is std::cref:

template< class T >
std::reference_wrapper<const T> cref( const T& t ) noexcept;
template <class T>
void cref(const T&&) = delete;

cref is used to convert an object reference to reference_wrapper. This can be used for example with std::bind: std::bind parameters are copied into the resulting object. But with cref, it becomes just a reference. So, cref must not be used with temporary parameters.

If the second overload wasn't deleted, then for example, cref(2) would be a valid expression (as a temporary can be bound to a const reference). This is a problem, as cref would return a reference to an object which will be destroyed. To disallow this, we need to delete functions where cref is passed a temporary, and this is what the second deleted overload does.

Gaming answered 4/8, 2018 at 7:53 Comment(8)
valid example thanks ... it turns out = delete is used to limit the number of foot-guns, which are (for some) a C++ ISO committee logic, difficult to comprehend ...Pryce
@ChefGladiator: this is one use case. Too bad that this question got closed, because I'm curious about other use cases. I'm sure that there are more.Gaming
I agree + I did not close this question. Indeed std::cref is used in both questions as an answer. As a use-case what I am interested in is why not "just use" static_assert inside, for example, std::cref to disallow const reference usage. static_assert can provide the explanation on false, as a second argumentPryce
@geza: Why are you sad this question got closed? Any good answer here is also a good answer to the other question -- this way all the answers get collected in one place, which is far more convenient for everyone.Uropygium
@BenVoigt: nothing serious, and I agree with you. The reason is that I'd like to have other example for non-member delete than cref. There must be some other, real-world example...Gaming
@geza: That would fit well on the older question, too. Hopefully a bounty will attract one (or more).Uropygium
@BenVoigt: a bounty is a good idea, thanks!Gaming
@geza: You might have noticed that Barry added some more examples and explanation to his answer and earned the bounty.Uropygium

© 2022 - 2024 — McMap. All rights reserved.