clang,返回带有类型转换的std :: unique_ptr

时间:2016-04-20 18:53:36

标签: c++ clang c++14

这是我的代码:

#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

2 个答案:

答案 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);
}