Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

c++ - Why do C++11-deleted functions participate in overload resolution?

Why does C++11 make "deleted" functions participate in overload resolution?
Why is this useful? Or in other words, why are they hidden instead of being deleted entirely?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Half of the purpose of the = delete syntax is to be able to prevent people from calling certain functions with certain parameters. This is mainly to prevent implicit conversions in certain specific scenarios. In order to forbid a particular overload, it has to participate in overload resolution.

The answer you cite gives you a perfect example:

struct onlydouble {
  onlydouble(std::intmax_t) = delete;
  onlydouble(double);
};

If delete removed the function entirely, that would make the = delete syntax equivalent to this:

struct onlydouble2 {
  onlydouble2(double);
};

You could do this:

onlydouble2 val(20);

This is legal C++. The compiler will look at all constructors; none of them take an integer type directly. But one of them can take it after an implicit conversion. So it'll call that.

onlydouble val(20);

This is not legal C++. The compiler will look at all constructors, including the deleted ones. It will see an exact match, via std::intmax_t (which will exactly match any integer literal). So the compiler will select it and then immediately issue an error, because it selected a deleted function.

= delete means "I forbid this," not merely, "This does not exist." It's a much stronger statement.

I was asking why the C++ standard says = delete means "I forbid this" instead of "this does not exist"

It's because we don't need special grammar to say "this does not exist." We get this implicitly by simply not declaring the particular "this" in question. "I forbid this" represents a construct that cannot be achieved without special grammar. So we get special grammar to say "I forbid this" and not the other thing.

The only functionality you would gain by having an explicit "this does not exist" grammar would be to prevent someone from later declaring it to exist. And that's just not useful enough to need its own grammar.

there is otherwise no way to declare that the copy constructor does not exist, and its existence can cause nonsensical ambiguities.

The copy constructor is a special member function. Every class always has a copy constructor. Just as they always have a copy assignment operator, move constructor, etc.

These functions exist; the question is only whether it is legal to call them. If you tried to say that = delete meant that they didn't exist, then the specification would have to explain what it means for a function to not exist. This is not a concept that the specification handles.

If you attempt to call a function that hasn't been declared/defined yet, then the compiler will error. But it will error because of an undefined identifier, not because of a "function doesn't exist" error (even if your compiler reports it that way). Various constructors are all called by overload resolution, so their "existence" is handled in that regard.

In every case, there is either a function declared via identifier, or a constructor/destructor (also declared via identifier, just a type-identifier). Operator overloading hides the identifier behind syntactic sugar, but it's still there.

The C++ specification cannot handle the concept of a "function that does not exist." It can handle an overload mismatch. It can handle an overload ambiguity. But it doesn't know about what isn't there. So = delete is defined in terms of the far more useful "attempts to call this fail" rather than the less useful "pretend I never wrote this line."

And again, re-read the first part. You cannot do that with "function doesn't exist." That's another reason why it's defined that way: because one of the main use cases of the = delete syntax is to be able to force the user to use certain parameter types, to explicitly cast, and so forth. Basically, to foil implicit type conversions.

Your suggestion would not do that.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...