【问题标题】:clang error with std::unique_ptrstd::unique_ptr 的 clang 错误
【发布时间】:2015-12-20 22:59:47
【问题描述】:

我有一个名为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;

如何正确处理此类错误?

【问题讨论】:

  • 你能提供一个mcve吗?
  • @CoryKramer 这个问题明确说明了这一点。 “我有一个名为IList 的基础对象。然后我有VectorList,它继承了IList。”
  • 不要忘记虚拟析构函数,以便它与unique_ptr 正常工作。
  • @CoryKramer 这里的重点是vlist 的类型与返回类型相同。 vlistunique_ptr&lt;VectorList&gt;,返回类型是 unique_ptr&lt;IList&gt;。所以标准的那个条款(“先尝试一下”)不适用。

标签: c++ clang c++14 unique-ptr


【解决方案1】:

在这方面,Clang 似乎(您的版本)仍在遵循 C++11 的行为。在 C++11 中,这种情况下必须使用 std::move,因为 vlist 的类型与返回类型不同,所以“返回左值时,首先尝试将其作为右值”的子句做到了不适用。

在 C++14 中,取消了“需要相同类型”的限制,因此在 C++14 中,您不需要在 return 语句中使用 std::move。但是,如果您需要使用当前的工具链编译代码,只需将其添加到那里:

return std::move(vlist);

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

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

必须满足复制省略的标准(包括“相同类型”);它们只是稍微扩展以涵盖参数。

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

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

(强调我的)

如您所见,return 案例不再需要复制省略条件。

【讨论】:

  • @Barry 我添加了来自 N4140 的报价。他们没有更改复制省略要求,但放宽了 return 语句中的要求。
  • 那么this 不应该使用g++ -std=c++11 进行编译,对吧?
  • @Barry 我相信“或”比“和”具有更弱的约束力,即我将其读作“当满足复制省略的标准时......或者当 表达式 in..."
  • @Columbo 哦,是这样(条件满足而不是异常和左值)还是(返回语句名称对象)?这就是为什么我们不写 82 字的句子,男孩和女孩。
  • @Angew 好吧,没有人出售编译器的“符合 C++11”认证。这基本上意味着即使在 C++11 模式下,您也可以看到编译器实现 C++14 行为。
猜你喜欢
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 2015-10-11
  • 2020-03-07
  • 1970-01-01
相关资源
最近更新 更多