我有一个叫做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是一个函数形参,要复制的对象由左值指定,重载解析为首先执行复制的选择构造函数,就好像对象是由右值指定的. ...
必须满足副本省略的标准(包括"相同类型");它们只是稍微扩展了一下,以涵盖参数。
在c++ 14 (N4140)中,措辞更广泛:
12.8/32当满足删除复制/移动操作的条件,但不满足异常声明的条件时,和要复制的对象由左值、指定,或者当
return
语句中的表达式是(可能是)(括号)id-表达式,命名在body或中声明具有自动存储持续时间的对象参数声明子句最内层封闭函数或lambda表达式,重载解析首先执行为复制选择构造函数的操作,就好像对象是由右值指定的。
(强调我的)
可以看到,对于return
情况,不再需要复制省略条件。