c++ 关于std::move的一些信息

0sgqnhkj  于 2022-12-27  发布在  其他
关注(0)|答案(1)|浏览(202)
std::string str1 = "hello";
std::string &&str2 = std::move(str1);
std::string str3(str2);
std::cout << str1 << std::endl;

我认为在第3行str3会窃取str1,因为std::string(std::string &&str)(或类似的东西)会被调用,但结果是:

test_move()
hello
test_move()

我想知道为什么内容str1仍然在第3行之后。

std::string str1 = "hello";
std::string &&str2 = std::move(str1);
std::string str3(str2);
std::cout << str1 << std::endl;

std::string str4(std::move(str1));
std::cout << str1 << std::endl;

我尝试将str1直接移到str4,结果是:

test_move()
hello 

test_move()

所以我无法区分str4和str3的情况有什么不同,在我看来它们都是一样的,都是以一个右值ref作为参数,但是移动语义只发生在str4上,为什么?

41zrol4v

41zrol4v1#

std::move实际上并没有移动任何东西,它只是创建了一个右值引用。
但是因为你用这个右值引用初始化了一个变量,所以变量本身变成了一个左值。把实际的右值传递给一个右值构造函数(如第二个例子所做的),构造函数会执行“移动”。
如果我们创建一个小的示例程序:

#include <iostream>
#include <utility>

struct Foo
{
    Foo() = default;

    Foo(Foo const&)
    {
        std::cout << "l-value copy construction\n";
    }

    Foo(Foo&&)
    {
        std::cout << "r-value move construction\n";
    }
};

int main()
{
    {
        Foo a;
        Foo&& b = std::move(a);
        Foo c(b);
    }

    {
        Foo a;
        Foo b(std::move(a));
    }
}

如果你构建并运行它,那么你会看到它会在你的第一个案例中调用左值复制构造函数。
看到它正在运行,例如here

相关问题