为什么 make_shared 会破坏右值引用?

Why does make_shared destroy rvalue-references?

我正在尝试了解我应该如何有效地使用智能指针,并且我很好奇它们如何与右值引用一起工作。为什么 std::make_shared(大概 make_unique 也是)使用复制语义而不是移动语义?

这是一个 gtest 测试,展示了我想说的内容

#include <memory>
int dtor_calls = 0;
struct MoveSemanticsTest1 {
    int data;
    ~MoveSemanticsTest1() { dtor_calls++; }
};

void reset_move_dtor_calls() {
    dtor_calls = 0;
}

TEST(MoveSemanticsSanityTest1, SanityTests) {
    reset_move_dtor_calls();
    {
        MoveSemanticsTest1 a = MoveSemanticsTest1();
    }
    EXPECT_EQ(1, dtor_calls); // <-- This passes, makes sense
    reset_move_dtor_calls();
    {
        MoveSemanticsTest1 b = {3};
        auto a = std::make_shared<MoveSemanticsTest1>(std::move(b));
    }
    EXPECT_EQ(1, dtor_calls); // <-- This fails, why?
    reset_move_dtor_calls();
    {
        MoveSemanticsTest1 b = {3};
        auto a = std::make_shared<MoveSemanticsTest1>(b);
    }
    EXPECT_EQ(2, dtor_calls); // <-- This passes, makes sense because of the copying
}

第二个 EXPECT_EQ 失败,这暗示移动的 b 资源实际上并未移动资源。

reset_move_dtor_calls();
{
    MoveSemanticsTest1 b = {3};  //1 
    auto a = std::make_shared<MoveSemanticsTest1>(std::move(b));  //2
    //3
    //4
}

在 1) 中创建一个 MoveSemanticsTest1

在 2) 中,您通过移动构造创建了一个 MoveSemanticsTest1,并将其赋予 shared_ptrb 处于 "moved from" 状态,但仍然在这里。

在 3) 你摧毁了 shared_ptr => 它摧毁了它的 MoveSemanticsTest1

在 4) 你摧毁了 MoveSemanticsTest1 b.

我计算了 2 次对析构函数的调用。