将unique_ptr <object>作为unique_ptr <const object =“”>返回

时间:2018-05-05 07:21:41

标签: c++ c++11 return const unique-ptr

我有这样的方法:

std::unique_ptr<const Stats> Table::GetStats() const {
  std::unique_ptr<Stats> result;
  // ...
  // Prepare stats. Under some conditions an exception may be thrown.
  // ...
  return result;
}

问题在于它无法编译:

  

错误:无法将'std :: unique_ptr'左值绑定到'std :: unique_ptr&amp;&amp;'

我可以使用以下旁路进行编译:

return std::unique_ptr<const Stats>(result.release());

但这似乎有点过分。我无法理解,从C ++的角度看第一段代码有什么问题?有更优雅的解决方案吗?

1 个答案:

答案 0 :(得分:4)

您的代码应该可以正常运行,因为在return statement

(强调我的)

  

(自C ++ 11起)

     

如果表达式是左值表达式和复制条件   除了表达式名称a之外,符合或将被满足   函数参数,然后重载决策选择构造函数   用于初始化返回值的执行两次:   首先好像表达式是一个右值表达式(因此它可以选择   移动构造函数或引用const的复制构造函数,   如果没有合适的转换,则重载分辨率为   第二次执行,使用左值表达式(因此可以选择   复制构造函数引用非const)。

     

即使函数返回类型不同,上述规则也适用   从表达的类型(复制elision需要相同的类型)

这意味着,即使result是左值,它首先会被视为右值,然后会选择以下constructor,它可以将std::unique_ptr<Stats>转换为{{ 1}}。

std::unique_ptr<const Stats>

似乎gcc4.9.2没有这样的表现(即首先将表达式视为右值表达式); gcc 9工作正常。

作为@RichardHodges commented,您可以使用template< class U, class E > unique_ptr( unique_ptr<U, E>&& u ) noexcept; 作为workaround