可能重复:
C ++ 11-删除功能为何参与重载决议?
我对下面的C ++代码11两个问题:
#include <iostream>
using namespace std;
struct A {
A() { cout << "Default c-tor" << endl; }
A(const A&) { cout << "Copy c-tor" << endl; }
A(A&&) = delete;
};
A f()
{
A a;
return a;
}
int main()
{
A b = f();
return 0;
}
我与海湾合作委员会和铛以下编译错误
GCC-4.7.2(克++ --std = C ++ 11 main.cpp中):
main.cpp: In function ‘A f()’:
main.cpp:16:9: error: use of deleted function ‘A::A(A&&)’
main.cpp:8:2: error: declared here
main.cpp: In function ‘int main()’:
main.cpp:21:10: error: use of deleted function ‘A::A(A&&)’
main.cpp:8:2: error: declared here
LIB-3.0(铛++ --std = C ++ main.cpp中11):
main.cpp:19:4: error: call to deleted constructor of 'A'
A b = f();
^ ~~~
main.cpp:8:2: note: function has been explicitly marked deleted here
A(A&&) = delete;
^
1 error generated.
- 不宜编译器使用拷贝构造函数,如果移动构造函数被明确删除?
- 有谁知道“不可移动的”类型有什么用处?
提前致谢。
A(A&&) = delete;
声明和其定义为delete
确实还声明它,不让它完全不存在。 相反,它类似 (但不相同)宣布其空和私人。 像这样:
private:
A(A&&){}
事实上,这是有时用于其他运营商之前的伎俩= delete
是可用的。 再次,它存在于查找的感觉,但称它是不是从来都不允许在C ++调用权限(在几乎或全部的情况下),一切完成后,诸如重载,名称查找。
标准居然说(8.4.3)
删除的功能是隐式内联。
还有的指出(我发现)说,删除的功能不应该参与名称查找。
另外,从8.4.3
引用删除的功能,或明或暗地的程序,除了宣布它,是形成不良。 [注:这包括调用函数隐式或显式地和形成指针或指针到部件的功能。 它适用即使未潜在的评估表达式引用。
当您删除移动构造函数,它不会从组由名称查找发现功能将其删除。 每当你的代码通常会使用移动的构造函数,你会因为即使人们发现,它已被删除得到一个错误。
你在你的代码的两个动作。 第一种是当你return a
,因为当复制省略是可能的,将被复制的对象是由左值(指定的a
,在这里),它被视为一招。 第二个是在分配A b = f()
因为f()
是给你还未被绑定到的基准的暂时的。
如果你想拷贝构造函数进行,而不是删除移动构造函数中,你应该摆脱你删除的定义。
这是一个有点研究的任务,但我想声明的举动构造指出,此举构造函数是要考虑的。 当它然后获取delete
d,这意味着对象可以移动,其中如果有一个移动构造函数,他们可以被移动。 如果你想这是不移动,但复制的对象,你只是声明一个拷贝构造函数,你不会提举构造。
我还没有完全找到了标准的说法,然而,其中明确规定上述但注意在12.8 class.copy]第9款备份部分上面的语句:
[注:当移动构造函数是不是隐含声明或明确提供,否则将援引此举构造可以改为调用拷贝构造函数表达式。 末端注]
从C ++工作草案2012年11月2日
8.4.3删除定义[dcl.fct.def.delete]
...
2,其指的是一个已删除的功能隐含或明确的程序,除了申报它,是形成不良的。 [ 注 :这包括调用函数隐式或显式地和形成指针或指针到部件的功能。 它适用即使未潜在的评估表达式引用。 如果一个函数被重载,如果函数是由过载分辨率来选择它仅被引用。 - 注完]
...
4删除的功能是隐式地内联。
由于被删除的移动构造函数被引用,是形成不良的程序。
A“使用”为不可移动的类型可以防止移动,所以防止返回本地对象。 我还没有见过这样的用法我自己,我不知道这是否有道理可言,但情况因人而异。