这是我的代码:
#include <memory>
struct A{};
struct B: A {};
std::unique_ptr<A> test()
{
auto p = std::make_unique<B>();
return p;
}
int main(int argc, char **argv)
{
test();
return 0;
}
它不能在clang上编译错误:
main.cpp:11:12: error: no viable conversion from returned value of type 'unique_ptr<B, default_delete<B>>' to function return type 'unique_ptr<A, default_delete<A>>'
然而,根据this(同样的情况),它应该。 我误解了什么吗?
我的命令行(clang ver 3.7):
clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
答案 0 :(得分:6)
这是一个铿锵的错误。来自[class.copy]:
当满足复制/移动操作的省略标准时,但不符合异常声明,以及 当
return
语句中的表达式为(可能)时,要复制的对象由左值或指定 括号中的 id-expression ,用于在主体中声明自动存储持续时间的对象 最里面的封闭函数的 parameter-declaration-clause 或 lambda-expression ,重载解析 选择复制的构造函数首先执行,就好像该对象是由右值指定。
不符合elision标准(因为p
与函数的返回类型的类型不同),但代码应该仍然有效,因为重载解析应该像{一样完成{1}}是一个左值。
那就是说,你确实希望移动elision发生,所以在这种情况下更喜欢不使用p
:
auto
clang接受此代码和移动elision将会发生。赢了。
答案 1 :(得分:3)
您需要来自unique_ptr的move
。以下代码在CLang和gcc上编译:
#include <memory>
struct A{};
struct B: A {};
std::unique_ptr<A> test()
{
auto p = std::make_unique<B>();
return std::move(p);
}