Что происходит: C++ std::move на std::shared_ptr увеличивает use_count?

Я всегда предполагал, что std::move() на std::shared_ptr крадет указатель и устанавливает указатель оригинала на nullptr -thus, не увеличивая счетчик ссылок. Это не похоже на правду в моем мире.

НАСТРОЙКА:

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().

ВОПРОС:

Что здесь происходит?

Ответы

Ответ 1

What is going on, here?

В MacOS кажется, что вы должны явно включить сематику перемещения с помощью -std=c++11 (или более поздних стандартов) ¹. В противном случае пример может быть скомпилирован (т.е. std::shared_ptr из связанной реализации библиотеки можно использовать), но он не работает должным образом, так как требуемые языковые функции не включены. Это приводит к тому, что вместо конструкций перемещения создаются реальные копии. Было бы лучше, если бы пакет AppleClang даже не позволял создавать экземпляры std::shared_ptr, когда требуемые языковые функции не включены.

Thanks) Спасибо @t.niese за тестирование данного компилятора/платформы.