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 ©) : 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;
}