我有一个名为IList
的基础对象。然后我有VectorList
,继承IList
。
然后我有这样的功能:
std::unique_ptr<IList> factory(){
auto vlist = std::make_unique<VectorList>();
return vlist;
}
此编译在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;
如何正确处理此类错误?
答案 0 :(得分:16)
看来(你的版本)Clang在这方面仍然遵循C ++ 11的行为。在C ++ 11中,在这种情况下你必须使用std::move
,因为vlist
的类型与返回类型不同,所以&#34;的子句在返回左值时,请尝试它首先作为右值&#34;不适用。
在C ++ 14中,对#34;相同类型的限制需要&#34;被解除了,所以在C ++ 14中,你不应该在return语句中需要std::move
。但如果您需要使用当前工具链编译代码,只需将其添加到那里:
return std::move(vlist);
确切的C ++ 11措辞是:
12.8 / 32 当满足或将满足复制操作的省略标准时,除了源的事实 object是一个函数参数,要复制的对象由左值,重载决策指定 选择首先执行复制的构造函数,就好像该对象是由rvalue指定的一样。 ...
必须满足复制省略的标准(包括&#34;相同类型&#34;);它们只是略微扩展以涵盖参数。
在C ++ 14(N4140)中,措辞更广泛:
12.8 / 32 当满足复制/移动操作的省略标准时,但异常声明,和 要复制的对象由左值,指定,或者在
return
语句中的表达式为(可能) 括号中的 id-expression ,用于在主体中声明自动存储持续时间的对象 最内层封闭函数的 parameter-declaration-clause 或 lambda-expression, 重载解析 首先执行选择复制的构造函数,就好像该对象是由右值指定的。
(强调我的)
如您所见,return
案例不再需要复制省略标准。