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