【问题标题】:C++ - Return const unique_ptrC++ - 返回 const unique_ptr
【发布时间】:2017-07-24 11:44:08
【问题描述】:

我想知道为什么编译时会出错:

const std::unique_ptr<int> get() { 
    return std::make_unique<int>(10);
}

int main() { 

    const std::unique_ptr<int> value = get();

    return EXIT_SUCCESS;
}

我收到以下错误:

main.cpp: In function ‘int main()’:
main.cpp:10:44: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
     const std::unique_ptr<int> value = get();

当我从 get 签名中删除 const 时,它可以正确编译。

有没有办法返回一个常量 unique_ptr ?

【问题讨论】:

  • 实际的std::unique_ptr 对象应该是常量,还是它指向的数据?
  • @MooingDuck 作为返回类型,这很奇怪。否则,pimpl comes to mind as a case where a const unique_ptr to a non-const object is sometimes used. 总的来说 const 指向非 const 的指针没有什么奇怪的。如果将指针指向其他地方是错误的,但通过指针改变指向的对象是正确的,则指向非 const 的 const 指针会表达并强制执行这一点。如果一个人遵循某种常见的做法,即把大多数东西都设为 const,除非有理由不这样做,那么指向非 const 对象的 const 指针就会经常出现。
  • @EliahKagan:pimpl 中的const 指针使移动/交换比需要的慢,但是是的,一般情况下,在某些情况下 const 指针是有意义的。
  • 这是一个 x/y 问题,我不知道为什么它的投票率如此之高。您声明您希望unique_ptr 保持不变,尽管const 返回值即使在像unique_ptr 这样的不可复制类型被添加到组合中之前也足够奇怪,但没有解释为什么您认为您想要这种奇怪的东西。我不觉得“为什么我不能做[没有任何明显理由的奇怪事情]”的问题很有用,否则我可以花一整天的时间来发明和发布它们。
  • @MooingDuck 似乎在很多情况下const 指针是一个好主意,至少如果其中一个值const-正确性。当然,如果我们可以完全控制函数签名,则应该使用引用。但是,想到接收指针的一个简单示例是像find_if 这样的stdlib 算法在容器中保存指针的范围内(reference_wrapper 似乎不值得麻烦&应该是const 本身! )。如果有可能在接收函数中意外改变指针,并且发生这种情况,它不会有好的结局。

标签: c++ c++11


【解决方案1】:

因为unique_ptr 是常量,所以不能移动只能复制。并且不允许复制unique_ptr(否则它不会是“唯一的”)。

如果指针指向的数据应该是常量,则使用std::unique_ptr&lt;const int&gt;

【讨论】:

  • 请注意:由于保证复制省略,OP 的示例必须在 C++17 中编译。
  • @bogdan 你确定吗?它不能为我在 clang、gcc 或 msvc 上编译 -std=c++17
  • @bogdan std::unique_ptr 复制构造函数和复制赋值运算符标记为delete,这意味着它不能用于任何类型的复制,即使可以省略复制.
  • @patatahooligan 这些可能是旧版本的编译器吗?它确实为我使用了这三个版本的最新版本,Clang 5,GCC 7.3,MSVC 15.9。
  • @Someprogrammerdude 这是真的,在这种情况下适用于 C++17 之前的任何内容。由于采用P0135,C++17 中的规则发生了变化。基本原理和示例在R0 version of the paper 中。基本上,从与目标相同类型的纯右值初始化不再被视为可以省略的临时复制/移动;它根据prvalue显式创建目标对象;没有什么可以忽略的了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-27
  • 1970-01-01
  • 2013-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多