【问题标题】:Why Does Getting/Setting Auto_Ptr Cause This Compiler Error为什么获取/设置 Auto_Ptr 会导致此编译器错误
【发布时间】:2015-06-18 07:40:34
【问题描述】:

我有一个 auto_ptr 的地图,我只是想设置和获取地图元素,但它会产生编译器错误。我不明白编译器错误是什么意思,出了什么问题?

获取编译器错误:

[错误] 将 'const std::auto_ptr' 作为 'this' 参数传递 'std::auto_ptr<_tp>::operator std::auto_ptr_ref<_tp1>() [with _Tp1 = 诠释; _Tp = int]' 丢弃限定符 [-fpermissive]

设置编译器错误:

[错误] 'operator=' 不匹配(操作数类型为 'std::map, std::auto_ptr >::mapped_type {aka std::auto_ptr}' 和 'int*')

我还听说不建议在标准 c++ 库集合(列表、向量、地图)中使用 auto_ptr。在下面的代码中我应该使用什么样的智能指针?

std::map <std::string, std::auto_ptr<int> > myMap;

// Throws compiler error
std::auto_ptr <int> a = myMap["a"];
// Also throws compiler error
myMap["a"] = new int; 

【问题讨论】:

  • 使用unique_ptrauto_ptr 将很快从 C++ 中删除。
  • @chris unique_ptr 在这里也不起作用(它已删除复制分配)
  • @MattMcNabb,好点,你不能做第一个(第二个应该没问题)。那时,问题是您是要与地图共享所有权还是从地图中获取所有权。
  • @MattMcNabb: unique_ptr 可能是一个合理的选择,但 std::auto_ptr &lt;int&gt; a = myMap["a"]; 应该更新为例如const std::auto_ptr&lt;int&gt;&amp; a = myMap["a"];,类似地更改指针应该使用unique_ptr API:myMap["a"].reset(new int);shared_ptr 的另一种选择......

标签: c++ smart-pointers


【解决方案1】:

首先,不要使用auto_ptr。它破坏了语义并已被弃用。单一所有权语义的正确指针是 unique_ptr

你可以拥有:

std::map<std::string, std::unique_ptr<int> > myMap;

现在,当您编写myMap["a"] 时,将为"a" 在映射中创建一个条目,这将返回对它的引用。创建的条目是std::unique_ptr&lt;int&gt;{},它是一个“空”指针。

您可以在某处提出这一点,但是您使用成员函数reset,而不是赋值运算符:

myMap["a"].reset( new int{5} );

或者,从 C++14 开始,

myMap["a"] = std::make_unique<int>(5);

如果您想要单一所有权,那么您的另一个不太有意义。您可以查看原始指针值,也可以获取所有权。取得所有权:

std::unique_ptr<int> new_owner = std::move(myMap["a"]);

这将使现有的映射条目再次成为“空”指针,new_owner 拥有所有权。

如果您只想对映射中的原始指针做一些事情,那么您可以使用get() 来获取该指针,或者直接在unique_ptr 上使用取消引用运算符:

myMap["a"].reset( new int{5} );
int *raw = myMap["a"].get();
*myMap["a"] = 6;

【讨论】:

  • 请注意,第一段不是意见。 std::auto_ptr 的语义与std::map 的语义不兼容。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 2016-05-13
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
相关资源
最近更新 更多