【问题标题】:What is going on: C++ std::move on std::shared_ptr increases use_count?发生了什么:C++ std::move on std::shared_ptr 增加了 use_count?
【发布时间】:2020-01-11 02:44:34
【问题描述】:

我一直假设std::shared_ptr 上的std::move() 窃取指针并将原始指针设置为nullptr - 因此不会增加引用计数。在我的世界里,这似乎不是真的。

设置

MacOS, g++ -version => "Apple LLVM 版本 10.0.1 (clang-1001.0.46.3)"

代码

#include <cstdio>                                                                                                                                                                                  
#include <memory>
class Thing { public: Thing(int N) : value(N) {} int value; };

void print(const char* name, std::shared_ptr<Thing>& sp)
{ printf("%s: { use_count=%i; }\n", name, (int)sp.use_count()); }

int main(int argc, char** argv) {
    std::shared_ptr<Thing>  x(new Thing(4711));
    print("BEFORE x", x);
    std::shared_ptr<Thing>  y = std::move(x);
    y->value = 4712;
    print(" AFTER x", x);
    print(" AFTER y", y);
    return 0;
}

输出

编译 (g++ tmp.cpp -o test),运行 (./test),交付

BEFORE x: { use_count=1; }
 AFTER x: { use_count=2; }
 AFTER y: { use_count=2; }

因此,使用std::move() 时引用计数会增加。

问题

这是怎么回事?

【问题讨论】:

  • 修复 UB can't reproduce.
  • FWIW 我(几乎)使用相同的版本,并且库代码与报告不匹配 iff _LIBCPP_HAS_NO_RVALUE_REFERENCES 未定义

标签: c++ macos shared-ptr rvalue-reference


【解决方案1】:

这是怎么回事?

在 MacOS 上,您似乎必须使用 -std=c++11(或更高标准)显式启用移动语义学¹。否则,该示例恰好可以编译(即,来自相关库实现的std::shared_ptr 可用)但由于未启用所需的语言功能而无法正常工作。这导致制作实际副本而不是移动构造。如果 AppleClang 包在未启用所需的语言功能时甚至不允许 std::shared_ptr 的实例化,那就更好了。

¹) 感谢 @t.niese 测试给定的编译器/平台。

【讨论】:

  • @lubgr 我可以确认您的代码将在use_count=2; 上编译并在mac 上使用给定的编译器运行,但会在例如use_count=1; 上产生。魔杖盒。
  • @lubgr 但仅在使用g++ tmp.cpp -o testg++ -std=c++11 tmp.cpp -o testg++ -std=c++17 tmp.cpp -o test 编译时才会显示use_count=1;
  • 听起来使用的标准库允许在不启用语言支持(移动语义)的情况下使用 C++11 功能 (std::shared_ptr),从而生成实际副本。
  • @lubgr;您的最后一条评论似乎指向了正确的方向。你或其他人能从中得出答案吗?
  • @lubgr 默认情况下它使用 pre c++11 编译。所以是的,std::move 什么都不做,只创建一个副本。
猜你喜欢
  • 1970-01-01
  • 2017-06-11
  • 2016-09-04
  • 2017-07-25
  • 2020-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
相关资源
最近更新 更多