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

What is going on: C++ std::move on std::shared_ptr increases use_count?

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

设置

MacOS,g++ -版本 => "Apple LLVM version 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() 时引用计数会增加。

问题:

这是怎么回事?

What is going on, here?

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

¹) 感谢@t.niese 测试给定的 compiler/platform.