= 函数声明后删除的含义
class my_class
{
...
my_class(my_class const &) = delete;
...
};
在这种情况下 =delete
是什么意思?
是否还有其他“修饰符”(除了 = 0
和 = delete
之外)?
class my_class
{
...
my_class(my_class const &) = delete;
...
};
What does = delete
mean in that context?
Are there any other "modifiers" (other than = 0
and = delete
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
删除函数是C++11 功能:
Deleting a function is a C++11 feature:
= 0
表示函数是纯虚函数,您无法从此类实例化对象。你需要从它派生并实现这个方法=delete
意味着编译器不会为你生成那些构造函数。 AFAIK 仅允许在复制构造函数和赋值运算符上使用。但我不太擅长即将到来的标准。= 0
means that a function is pure virtual and you cannot instantiate an object from this class. You need to derive from it and implement this method= delete
means that the compiler will not generate those constructors for you. AFAIK this is only allowed on copy constructor and assignment operator. But I am not too good at the upcoming standard.摘自《The C++ 编程语言 [第 4 版] - Bjarne Stroustrup》一书的这段摘录讨论了使用
=delete
背后的真正目的:This excerpt from The C++ Programming Language [4th Edition] - Bjarne Stroustrup book talks about the real purpose behind using
=delete
:由于似乎没有其他人回答这个问题,我应该提到还有
= default
。https:// learn.microsoft.com/en-us/cpp/cpp/explicitly-defaulted-and-deleted-functions#explicitly-defaulted-functions
Since it appears no one else answered this question, I should mention that there is also
= default
.https://learn.microsoft.com/en-us/cpp/cpp/explicitly-defaulted-and-deleted-functions#explicitly-defaulted-functions
我所使用的编码标准对于大多数类声明都有以下内容。
如果您使用这 6 个中的任何一个,只需注释掉相应的行即可。
示例:FizzBus 类仅需要 dtor,因此不使用其他 5 个。
我们在这里仅注释掉 1 个,并将其实现安装在其他位置(可能是编码标准建议的位置)。其他 5 个(共 6 个)不允许删除。
您还可以使用“=删除”来禁止不同大小值的隐式提升...示例
The coding standards I've worked with have had the following for most of class declarations.
If you use any of these 6, you simply comment out the corresponding line.
Example: class FizzBus require only dtor, and thus do not use the other 5.
We comment out only 1 here, and install the implementation of it else where (probably where the coding standard suggests). The other 5 (of 6) are disallowed with delete.
You can also use '= delete' to disallow implicit promotions of different sized values ... example
删除的函数是隐式内联的
(现有答案的附录)
...并且删除的函数应是函数的第一个声明(删除函数模板的显式特化除外 - 删除应在第一个)专业化的声明),这意味着您不能声明一个函数,然后在其翻译单元本地的定义处删除它。
引用 [dcl.fct.def.delete]/4< /a>:
删除了定义的主要功能模板可以进行专门化
,尽管一般的经验法则是为了避免专门化函数模板,因为专门化不参与重载决策的第一步,因此在某些情况下它可能很有用。例如,当使用没有定义的非重载主函数模板来匹配所有不希望隐式转换为其他匹配转换重载的类型时;即,通过仅在未定义、非重载的主函数模板的显式特化中实现精确类型匹配来隐式删除许多隐式转换匹配。
在 C++11 删除函数概念之前,人们可以通过简单地省略主函数模板的定义来做到这一点,但这会产生模糊的未定义引用错误,可以说没有给出作者的任何语义意图主要功能模板(故意省略?)。如果我们显式删除主函数模板,则在找不到合适的显式专业化的情况下的错误消息会变得更好,并且还表明主函数模板定义的省略/删除是故意的。
但是,可以删除主模板定义,而不是简单地省略上面主函数模板的定义,从而在没有显式专业化匹配时产生模糊的未定义引用错误:
产生更易读的错误消息,其中删除意图也很明确可见(其中未定义的引用错误可能会导致开发人员认为这是一个不经深思熟虑的错误)。
回到我们为什么要使用这种技术?同样,显式专业化对于隐式删除隐式转换可能很有用。
A deleted function is implicitly inline
(Addendum to existing answers)
... And a deleted function shall be the first declaration of the function (except for deleting explicit specializations of function templates - deletion should be at the first declaration of the specialization), meaning you cannot declare a function and later delete it, say, at its definition local to a translation unit.
Citing [dcl.fct.def.delete]/4:
A primary function template with a deleted definition can be specialized
Albeit a general rule of thumb is to avoid specializing function templates as specializations do not participate in the first step of overload resolution, there are arguable some contexts where it can be useful. E.g. when using a non-overloaded primary function template with no definition to match all types which one would not like implicitly converted to an otherwise matching-by-conversion overload; i.e., to implicitly remove a number of implicit-conversion matches by only implementing exact type matches in the explicit specialization of the non-defined, non-overloaded primary function template.
Before the deleted function concept of C++11, one could do this by simply omitting the definition of the primary function template, but this gave obscure undefined reference errors that arguably gave no semantic intent whatsoever from the author of primary function template (intentionally omitted?). If we instead explicitly delete the primary function template, the error messages in case no suitable explicit specialization is found becomes much nicer, and also shows that the omission/deletion of the primary function template's definition was intentional.
However, instead of simply omitting a definition for the primary function template above, yielding an obscure undefined reference error when no explicit specialization matches, the primary template definition can be deleted:
Yielding a more more readable error message, where the deletion intent is also clearly visible (where an undefined reference error could lead to the developer thinking this an unthoughtful mistake).
Returning to why would we ever want to use this technique? Again, explicit specializations could be useful to implicitly remove implicit conversions.
=delete
是 C++11 中引入的功能。根据=delete
不允许调用该函数。详细。
假设在一个班级里。
当调用此函数进行 obj 赋值时,这是不允许的。意味着赋值运算符将限制从一个对象复制到另一个对象。
= delete
is a feature introduce in C++11. As per=delete
it will not allowed to call that function.In detail.
Suppose in a class.
While calling this function for obj assignment it will not allowed. Means assignment operator is going to restrict to copy from one object to another.
一个总结一些常见用法的小例子:
TODO:
另请参阅
default
和delete
”部分A small example to summarize some common usages:
TODO:
See also
default
anddelete
"这是 C++ 0x 标准中的新事物,您可以在其中删除继承的函数。
This is new thing in C++ 0x standards where you can delete an inherited function.
事实上
,您可以通过使用左值引用限定符来反转此行为:
当然,您已经了解
const
限定符,它同样将“this”限制在 const 上下文中。易失性
将执行相同的上下文限制。您知道有
noexcept
。除了(类型..)
也是如此constexpr
,必须写在左侧。consteval
自 C++20 起用于严格的构建时间限制上下文。static
(左侧),这将限制链接,或使其成为类范围而不是方法。extern
我认为如果没有立即定义它通常是隐含的。inline
(左侧)同样会改变链接规则。您还可以添加属性,虽然它们不是限定符,但从语法上讲,我们应该能够将它们写在左侧和右侧,但我没有找到让我们写在右侧的编译器:
:
尾随返回类型:
请注意,如您所知,资格应出现在
->
virtual
之前。覆盖
。final
如果这是类型层次结构中最低的虚拟函数。显式
。friend
在左侧。尝试
一个非常奇怪的。函数尝试块: https://en.cppreference.com/w/cpp/ language/try#Function_try_block:
S() : mem(0) {}
requires
模板概念子句::
:
As a matter of fact, you can reverse this behavior by using a lvalue reference qualifier:
Of course you already know about the
const
qualifier, which similary restricts "this" to be in a const-context.volatile
will do the same context restriction.There is
noexcept
which you know.except(types..)
tooconstexpr
which has to be written on the left side.consteval
since C++20 for strict build time restriction context.static
(left side) which will limit linkage, or make it a class scope instead of method.extern
I think it's usually implied if not immediately defined.inline
(left side) which similarly changes linkage rules.You can also add attributes, they aren't qualifiers though but syntaxically we are supposed to be able to write them on the left and right, but I didn't find a compiler that let us write on the right:
:
trailing return type:
Note that qualification shall appear before
->
virtual
as you know.override
in case of virtual functions that you want to make sure respects its base prototype.final
if that's the lowest virtual function in the type hierarchy.explicit
for converting constructors.friend
on the left side.try
a very odd one. function try blocks: https://en.cppreference.com/w/cpp/language/try#Function_try_block:
S() : mem(0) {}
requires
clause for concepts on templates: