请考虑以下代码:
#include<memory>
struct A {
std::auto_ptr<int> i;
};
A F() {
A a;
return a;
}
int main(int argc, char **argv) {
A a = F();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译时我收到编译错误,(见这里):
error: no matching function for call to ‘A::A(A)’
A a = F();
^
Run Code Online (Sandbox Code Playgroud)
根据我的理解,A::A(A)甚至不允许存在,那么编译器为什么要求它呢?其次,为什么不使用RVO?
如果是因为std::auto_ptr无法从函数返回,为什么以下编译运行?
#include<memory>
std::auto_ptr<int> F() {
std::auto_ptr<int> ap;
return ap;
}
int main(int argc, char **argv) {
std::auto_ptr<int> ap = F();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不能在我目前的工作中使用C++ 11,因此使用auto_ptr.
我尝试搜索,但找不到相关的问答,即使我知道这是重复的。因此,我只是回答而不是投票关闭作为重复项。道歉。
它需要复制构造函数的原因是因为该行:
A a = F();
Run Code Online (Sandbox Code Playgroud)
实际上是(从编译器的角度来看):
A a(F());
Run Code Online (Sandbox Code Playgroud)
即使使用复制省略/RVO。也就是说,编译器不会执行以下操作:
// This is NOT what the compiler does for A a = F();
A a;
a = F();
Run Code Online (Sandbox Code Playgroud)
即使使用复制省略/RVO,也A a(F());不起作用。从 C++ 标准的角度来看,无论编译器是否进行复制省略,代码都必须是合法的。复制省略并没有放松需要复制构造函数的要求(即使它实际上没有使用它;它仍然需要存在以确保代码的“合法性”)。
这是行不通的,因为std::auto_ptr的复制构造函数不接受const引用,所以A的复制构造函数不存在。F()返回一个临时的A,它只能由const引用捕获,这意味着该行代码正在尝试使用不存在的复制构造函数。