发生了什么:C ++ std :: move on std :: shared_ptr增加了use_count?

Fra*_*fer 31 c++ macos shared-ptr rvalue-reference

我一直假设std::move()a上会std::shared_ptr窃取指针并将原始指针设置为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;
}
Run Code Online (Sandbox Code Playgroud)

输出

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

BEFORE x: { use_count=1; }
 AFTER x: { use_count=2; }
 AFTER y: { use_count=2; }
Run Code Online (Sandbox Code Playgroud)

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

问题

这里发生了什么?

lub*_*bgr 42

这里发生了什么?

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

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

  • @lubgr,但仅当使用`g ++ tmp.cpp -o test`,`g ++ -std = c ++ 11 tmp.cpp -o test或`g ++ -std = c ++ 17 tmp.cpp -o test进行编译时`它显示`use_count = 1;` (2认同)
  • 听起来好像使用的标准库允许使用C ++ 11功能(“ std :: shared_ptr”)而无需启用语言支持(移动语义),从而导致制作了实际的副本。 (2认同)