嗨,我正在研究C ++ 11,并且有一种我无法理解的行为:
std::unique_ptr<int> foo()
{
std::unique_ptr<int> p(new int(3));
return p; //1
}
int main()
{
std::unique_ptr<int> p2 = foo(); //2
}
编译
std::unique_ptr<int> p(new int(3));
std::unique_ptr<int> foo()
{
return p;
}
int main()
{
std::unique_ptr<int> p2 = foo(); //2
}
不要编译说我正在尝试使用已删除的操作(可能是复制),但是// 1和// 2都在制作不允许的对象的副本。
我读了标准:
当满足某些条件时,允许实现省略类对象的复制/移动构造[...]复制/移动操作的省略,称为复制省略,允许在...的返回语句中使用。具有类返回类型的函数,当表达式是非易失性自动对象的名称,其具有与函数返回类型相同的cv-nonqualified类型[...]
但这对我来说并不是很清楚。谢谢你的帮助。
答案 0 :(得分:3)
由于当前的问题,第1行和第2行都不应该编译,因为他们试图制作不可复制类型的副本。目前还不清楚这是你所看到和质疑的,或者这是你看不到的,还有质疑。
如果第1行或第2行为您编译,则这是编译器或std :: lib中的错误。
<强>更新强>
现在有一个新的不同的问题。
新问题声称这可以编译:
std::unique_ptr<int> foo()
{
std::unique_ptr<int> p(new int(3));
return p; //1
}
int main()
{
std::unique_ptr<int> p2 = p; //2
}
它不能为我编译。第一个错误是:
error: use of undeclared identifier 'std'
如果我#include <memory>
,则下一个错误是:
test.cpp:10:27: error: use of undeclared identifier 'p'
std::unique_ptr<int> p2 = p; //2
^
如果您没有看到这些错误,那么您的编译器/库就会出错。
更新2
现在还有第三个问题:
这确实为我编译:
#include <memory>
std::unique_ptr<int> foo()
{
std::unique_ptr<int> p(new int(3));
return p; //1
}
int main()
{
std::unique_ptr<int> p2 = foo(); //2
}
(我必须添加#include <memory>
才能让它编译)
但这正确无法编译:
#include <memory>
std::unique_ptr<int> p(new int(3));
std::unique_ptr<int> foo()
{
return p;
}
int main()
{
std::unique_ptr<int> p2 = foo(); //2
}
后一个错误位于上面未标记的行上:
return p;
这是一个错误,因为它试图复制p
不是可复制的类型。
标记为//2
的行不是错误,因为它没有尝试复制foo()
返回的prvalue。而是移动构建返回foo()
的值,这是使用可移动类型。
网上有许多关于移动语义的参考资料。 Here is one,虽然已过时了。但这很简单,并且可以了解各种想法的基础知识。