C++11 为什么可以';该副本不能自动替换为移动吗?

C++11 为什么可以';该副本不能自动替换为移动吗?,c++11,move-semantics,C++11,Move Semantics,测试类别: #include <iostream> #include <string> struct inner { std::string value; inner() : value("test") { std::cerr << "inner default construct\n"; } inner(inner &&mv) : value(

测试类别:

#include <iostream>
#include <string>

struct inner
{
        std::string value;

        inner() : value("test") {
                std::cerr << "inner default construct\n";
        }
        inner(inner &&mv) : value(std::move(mv.value)) {
                std::cerr << "inner move construct\n";
        }
        inner(inner const &copy) : value(copy.value) {
                std::cerr << "inner copy construct\n";
        }
};

struct outer
{
        inner value;
        outer() {}
        outer(inner v)
                : value(v)
        {}
};
。。。哪些产出:

内部默认构造

内移结构

内移结构

但这条主线做了我没想到的事情:

int main()
{
        inner i;
        outer o(std::move(i));
        return 0;
}
内部默认构造

内移结构

内部复制构造

我原以为拷贝会是另一个移动,就像在第一个主视图中一样。为什么在第一种情况下使用move的优化可用,而在第二种情况下不可用


我意识到我可以在
外部(内部v)
构造函数中显式调用std::move。。。。但为什么需要这样做?为什么编译器不能执行隐式移动?

您需要在初始值设定项列表中说
:value(std::move(v))

我不擅长C++11右值语义,但
外部
没有接受
内部
右值引用的构造函数,因此,编译器别无选择,只能进行
内部
复制,因为
外部
构造函数的输入参数是左值,因此在初始化
外部::v
成员时必须调用
内部
复制构造函数,而不是移动构造函数


mover()
示例中,您没有获得副本的原因可能是,如果输入
internal
实例可以直接移动到目标
q
变量,那么就不需要任何副本,从而调用
internal
move构造函数而不是copy构造函数。

我知道这会起作用,我的问题是,为什么需要这样做?我将对问题进行编辑以使其更清楚。@SoapBox:我不理解这个问题-如果没有
move
v
是左值,您无法获得move构造函数。“x”不是从函数返回时的l值吗(在我的第一个示例中)?为什么该值可以移动,但构造函数中的值不能移动?@SoapBox:
x
不是xvalue。在任何情况下,“返回时移动”规则都没有说明任何关于xvalue的内容。这是一条单独的规则。您可以移动到valueRight接受的参数中,当输入
内部
实例在传递到
外部
构造函数之前创建时,该参数将解释
内部移动构造
消息。但是在该构造函数内部,
internalv
参数是左值,而不是右值。由于左值不能绑定到右值引用,因此不能通过
内部
移动构造函数初始化
外部::v
成员,只能通过复制构造函数,从而初始化
内部复制构造函数
消息。
int main()
{
        inner i;
        outer o(std::move(i));
        return 0;
}