CPP*_*PPL 3 c++ deleted-functions
给出以下玩具代码:
class X
{
public:
X() { }
X(const X&) { }
//X(X&&) = delete;
};
int main()
{
X x;
X y = std::move(x);
}
Run Code Online (Sandbox Code Playgroud)
我知道X::X(X&&)在这种情况下它被隐式删除,因为它X(const X&)作为用户声明的构造函数存在。但我对这里术语“隐式删除”的含义有点困惑:如果我们取消注释,代码的行为会有所不同,这意味着隐式删除和“显式”删除X(X&&) = delete;之间存在差异。
我心中有两种不同的理解:
“隐式删除”意味着编译器生成一些类似于的代码X(X&&) = delete;(也就是说,编译器知道存在X(X&&)并且知道它X(X&&)被删除),但生成的代码X(X&&) = delete;在某种程度上不同于,当X y = std::move(x);尝试调用时X::X(X&&),编译器选择X(const X&)而不是报告错误。(如果X(X&&) = delete;取消注释,编译器不会选择X(const X&),会报错)
“隐式删除”意味着X(X&&)根本没有在类中声明,换句话说,编译器没有任何有关的信息X(X&&),因此X y = std::move(x);直接与X(const X&).
请问我的理解哪一个是正确的?
我的猜测是前者应该是正确的。因为如果我们把上面的代码改成如下:
class X
{
public:
X() { }
//X(const X&) { }
X(X&&) {}
};
int main()
{
X x;
X y = x;
}
Run Code Online (Sandbox Code Playgroud)
我们收到一条错误消息'X::X(const X &)': attempting to reference a deleted function,这意味着编译器知道X(const X &)它何时被隐式删除。
然而,对我来说,我的后一种理解似乎是一种更直接的完成工作的方式。所以我想知道为什么我们要设计“隐式删除”的概念(这也给我一种不一致的感觉,因为“隐式删除”需要与“显式删除”有不同的行为)
当您取消注释时X(X&&) = delete;,您所做的就是声明该 ctor 已删除。例如,这意味着它确实参与了重载决策,在以下情况下它会获胜X y = std::move(x);,但实际上不能使用,因为它缺少主体。
请注意,这并不专门适用于(特殊或非)成员函数,而是适用于一般函数:
\n#include<iostream>\n\n// this is akin to defining both copy and move ctor\nauto f(int) { std::cout << "int" << std::endl;}\nauto f(double) { std::cout << "double" << std::endl;}\n\n// this is akin to defining copy ctor and deleting move ctor\nauto g(int) { std::cout << "int" << std::endl;}\nauto g(double) = delete;\n\n// this is akin to defining only copy ctor\nauto h(int) { std::cout << "int" << std::endl;}\n// auto h(double) is not even delcared\n\nint main() {\n f(1);\n f(1.2);\n g(1);\n //g(1.2); // compile time error\n h(1);\n h(1.2); // round error\n}\nRun Code Online (Sandbox Code Playgroud)\n特殊成员函数的特殊之处在于声明/定义/ defaulting/ deleteing/根本不写一个函数如何影响另一个函数。
本页对所有内容进行了解释,但需要仔细阅读。
\n这是一个棘手的地方(我的粗体):
\n\n\n删除了隐式声明的移动构造函数
\n如果满足以下任一条件,则类的隐式声明或默认移动构造函数被
\nT定义为已删除:\n
\n- T 具有无法移动的非静态数据成员(具有已删除、不可访问或不明确的移动构造函数);
\n- [\xe2\x80\xa6]
\n[\xe2\x80\xa6]
\n
以上是什么意思?
\n这是一个例子:
\n// copyable but not movable\nstruct CNM {\n CNM() {};\n CNM(CNM const&) = default;\n CNM(CNM&&) = delete;\n};\n\nstruct W {\n W() {}\n W(W&&) = default; // defaulted... but actually deleted!\n CNM nm;\n};\n\nW w1;\nW w2{std::move(w1)}; // compile time error\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1193 次 |
| 最近记录: |