为什么C ++ 11删除的函数参与重载分辨率? [英] Why do C++11-deleted functions participate in overload resolution?

查看:118
本文介绍了为什么C ++ 11删除的函数参与重载分辨率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为什么C ++ 11使 delete d函数参与重载解决

为什么这很有用?

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?

推荐答案

<$ c $的一半目的c> = delete 语法是能够防止人们使用某些参数调用某些函数。这主要是为了防止在某些特定情况下的隐式转换。为了禁止一个特定的超载,它必须参与重载决策。

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);
};

如果 delete 将使 = delete 语法等价于:

struct onlydouble2 {
  onlydouble2(double);
};

您可以这样做:

onlydouble2 val(20);

这是合法的C ++。编译器将查看所有构造函数;它们都不直接接受整数类型。但是其中一个可以在隐式转换后接受它。

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);

这是不是 legal C ++。编译器将查看所有构造函数,包括 delete d。它将通过 std :: intmax_t (它将完全匹配任何整数文字)看到完全匹配。因此,编译器将选择它,然后立即发出错误,因为它选择了一个 delete d函数。

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.

code> = delete 表示我禁止这个,不仅仅是这不存在。这是一个更强大的语句。

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


我问为什么C ++标准说= delete意味着我禁止这个,而不是存在

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

这是因为我们不需要特殊的语法来说这不存在。我们通过简单地不声明特定的this隐含地得到这个。 我禁止这个表示不能没有特殊的语法实现的构造。所以我们得到特殊的语法,说我禁止这个,而不是其他的东西。

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.

这些函数存在;问题只是它是否是合法的。如果你试图说 = delete 意味着它们不存在,那么规范将必须解释函数不存在意味着什么。这不是规范处理的概念。

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.

C ++规范不能处理不存在的函数的概念。它可以处理过载不匹配。它可以处理过载模糊。但它不知道什么不是在那里。所以 = delete 是根据更有用的尝试称为失败而不是不那么有用的假装我从来没有写这行定义。

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."

再次,重新阅读第一部分。你不能这样做与功能不存在。这是为什么它定义的另一个原因:因为 = delete 语法的一个主要用例是能够强制用户使用某些参数类型,明确铸造,等等。基本上,隐藏类型转换。

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.

您的建议不会这样做。

这篇关于为什么C ++ 11删除的函数参与重载分辨率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆