【问题标题】:What's c++11 standard's equivalent for the deprecated std::auto_ptr? [duplicate]已弃用的 std::auto_ptr 的 c++11 标准等效项是什么? [复制]
【发布时间】:2013-07-12 21:18:11
【问题描述】:

我有一些使用 std::auto_ptr 的代码,并在编译时给出了关于已弃用 std::auto_ptr(Suse Linux 12.2 上的 GCC 4.7.1)的丑陋警告。

所以我尝试了以下方法(因为我找到了一些声明 std::unique_ptr 应该是适当的等价物的来源)

template<typename T>
struct AutoPtr
{
#ifdef COMPILE_FOR_CX11
    typedef std::unique_ptr<T> Type;
#else
    typedef std::auto_ptr<T> Type;
#endif
};

并将对std::auto_ptr&lt;T&gt; 的所有引用替换为AutoPtr&lt;T&gt;::Type,但使用此选项时出现编译错误。

我很确定我想在这些代码中使用std::auto_ptr 之类的东西,并且我知道它的罪魁祸首和缺陷。我得到的错误似乎与使用 std::unique_ptr 时的构造问题有关。

附带说明:用于构造的最终类是T的继承类型,代码如下:

class MockClass;

class Client
{
public:
    Client();
    Client(const Client& rhs);

private:
    mutable AutoPtr<MockClass>::Type embeddedMock;
};

Client::Client()
: embeddedMock(new ::testing::NiceMock<MockClass>())
//             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Getting errors here!
{
}


Client::Client(const Client& rhs)
: embeddedMock(rhs.embeddedMock)
{
}

那么,什么是完全兼容的 c++11 集合中的智能指针,我可以在这里使用?

【问题讨论】:

  • 包装类有点无意义。您可以只说#define AutoPtr std::auto_ptr 等,然后说AutoPtr&lt;T&gt;
  • 编译错误是什么?
  • 应该是mutable AutoPtr&lt;MockClass&gt;::Type embeddedMock;
  • @g-makulik:它似乎工作here
  • @AndyProwl:哎哟! mutable?哎哟!这是滥用mutable 的意图来解决设计的不同限制。两个错误不能使一个正确,即使它可以编译。

标签: c++ c++11


【解决方案1】:

unique_ptrauto_ptr 的 C++11 替换工具。但是,它不是直接替代品,因为auto_ptr 具有复制所有权转移语义,而unique_ptr 强制您显式转移所有权。当你有这样的事情时:

auto_ptr<Foo> x(new Foo());
// ...
auto_ptr<Foo> y = x;
// ...
bar( y ); // copies y into bar(), transferring ownership

。 . .要使用unique_ptr,您需要将move() 添加到所有权转移站点:

unique_ptr<Foo> x(new Foo());
// ...
unique_ptr<Foo> y = move(x);
// ...
bar( move(y) );

编辑:

在不知道您遇到什么具体错误的情况下,很难说出默认构造函数无法编译的原因。但是,除非添加了 move,否则您的复制构造函数应该无法使用 unique_ptr 进行编译。

【讨论】:

  • 但是mutable 声明的目的是什么。我很快就看到了一位知名 SO 成员的回答,该回答展示了如何明确使用转移 std::unique_ptr 的所有权,这将符合 std::auto_ptr。引入移动语义(对于应该为 c++ old 和 cx11 标准编译良好的代码)在这里没有多大帮助:(
  • @g-makulik,对,错过了mutable 部分。对不起。 (已编辑答案以更正复制构造函数引用。)如果您想制作在 C++11 和 C++98 下工作的代码,您始终可以引入一个在 C++98 下编译的虚拟 move-type 操作. IE。类似:#ifdef CPP11|#define MOVE(X) ::std::move(X)|#else|#define MOVE(X) X|#endif
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-14
  • 1970-01-01
  • 2010-09-11
相关资源
最近更新 更多