与std :: unique_ptr的clang错误

Nic*_*ick 11 c++ clang unique-ptr c++14

我有一个基础对象叫IList.然后我有VectorList,继承IList.

然后我有这样的功能:

std::unique_ptr<IList> factory(){
    auto vlist = std::make_unique<VectorList>();
    return vlist;
}
Run Code Online (Sandbox Code Playgroud)

这编译没有问题gcc,但clang给出以下错误:

test_file.cc:26:9: error: no viable conversion from 'unique_ptr<VectorList, default_delete<VectorList>>' to
      'unique_ptr<IList, default_delete<IList>>'
        return vlist;
Run Code Online (Sandbox Code Playgroud)

如何正确处理这种错误?

Rei*_*ica 17

看来(你的版本)Clang在这方面仍然遵循C++ 11的行为.在C++ 11中,您必须std::move在这种情况下使用,因为类型vlist与返回类型不同,因此"返回左值时,首先尝试将其作为右值"的子句不适用.

在C++ 14中,解除了"相同类型所需"的限制,因此在C++ 14中,您不应该std::move在return语句中使用它.但是如果您需要使用当前工具链编译代码,只需将其添加到那里:

return std::move(vlist);
Run Code Online (Sandbox Code Playgroud)

确切的C++ 11措辞是这样的:

12.8/32当满足或将满足复制操作的省略标准时,除了源对象是函数参数这一事实,并且要复制的对象由左值指定,重载决策选择构造函数为首先执行复制,就好像对象是由右值指定的一样....

必须满足复制省略(包括"相同类型")的标准; 它们只是稍微扩展到覆盖参数.

在C++ 14(N4140)中,措辞更广泛:

12.8/32当满足复制/移动操作的省略标准时,但不满足异常声明,并且要复制的对象由左值指定,或者当return语句中的表达式为(可能带有括号)时id-expression命名一个对象,该对象具有在最内层封闭函数或lambda-expression的body或parameter-declaration-clause声明的自动存储持续时间 ,首先执行重载决策以选择复制的构造函数,就好像该对象是由一个右值.

(强调我的)

如您所见,return案例不再需要复制省略标准.

  • @Columbo哦(标准遇到并且不是例外和左值)或(返回声明命名对象)?这就是为什么我们不写82个单词的句子,男孩和女孩. (4认同)
  • @Angew嗯,没有人为编译器销售"符合C++ 11"的认证.它基本上意味着你可以期望编译器即使在他们的C++ 11模式下也能实现C++ 14的行为. (2认同)