为什么在传递给另一个对象时,对 const 对象调用 std::move 会调用复制构造函数?
Why does calling std::move on a const object call the copy constructor when passed to another object?
为什么在 const
对象上调用 std::move 在传递给另一个对象时调用复制构造函数?具体来说,代码
#include <iostream>
struct Foo {
Foo() = default;
Foo(Foo && x) { std::cout << "Move" << std::endl; }
Foo(Foo const & x) = delete;
};
int main() {
Foo const x; Foo y(std::move(x));
}
编译失败并显示消息:
g++ -std=c++14 test07.cpp -o test07
test07.cpp: In function 'int main()':
test07.cpp:10:36: error: use of deleted function 'Foo::Foo(const Foo&)'
Foo const x; Foo y(std::move(x));
^
test07.cpp:6:5: note: declared here
Foo(Foo const & x) = delete;
^
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1
当然,我预计它会失败,因为我们无法移动 const
值。同时,我不明白代码在尝试调用复制构造函数之前采用的路线。意思是,我知道 std::move
将元素转换为 x 值,但我不知道 const
.
之后的事情如何进行
使用 T const
参数调用 std::move
的结果类型是 T const&&
,不能绑定到 T&&
参数。下一个最佳匹配是您的复制构造函数,它已被删除,因此出现错误。
显式 delete
一个函数并不意味着它不可用于重载解析,但如果它确实是重载解析选择的最可行的候选者,那么它就是一个编译器错误。
结果是有道理的,因为移动构造是一种从源对象窃取资源的操作,从而改变它,所以你不应该仅仅通过调用 const
对象就可以做到这一点 std::move
.
std::move(x)
的类型是 Foo const&&
,无法绑定到 Foo&&
。原因与 T const&
无法绑定到 T&
相同。但是,您可以让构造函数采用 Foo const&&
。您很可能无法真正 移动 相应对象的数据,但是,例如,在您的示例中没有数据,即以下代码可以正常工作:
#include <iostream>
struct Foo {
Foo() = default;
Foo(Foo &&) { std::cout << "Move\n"; }
Foo(Foo const&&) { std::cout << "Move const\n"; }
Foo(Foo const &) = delete;
};
int main() {
Foo const x; Foo y(std::move(x));
}
为什么在 const
对象上调用 std::move 在传递给另一个对象时调用复制构造函数?具体来说,代码
#include <iostream>
struct Foo {
Foo() = default;
Foo(Foo && x) { std::cout << "Move" << std::endl; }
Foo(Foo const & x) = delete;
};
int main() {
Foo const x; Foo y(std::move(x));
}
编译失败并显示消息:
g++ -std=c++14 test07.cpp -o test07
test07.cpp: In function 'int main()':
test07.cpp:10:36: error: use of deleted function 'Foo::Foo(const Foo&)'
Foo const x; Foo y(std::move(x));
^
test07.cpp:6:5: note: declared here
Foo(Foo const & x) = delete;
^
Makefile:2: recipe for target 'all' failed
make: *** [all] Error 1
当然,我预计它会失败,因为我们无法移动 const
值。同时,我不明白代码在尝试调用复制构造函数之前采用的路线。意思是,我知道 std::move
将元素转换为 x 值,但我不知道 const
.
使用 T const
参数调用 std::move
的结果类型是 T const&&
,不能绑定到 T&&
参数。下一个最佳匹配是您的复制构造函数,它已被删除,因此出现错误。
显式 delete
一个函数并不意味着它不可用于重载解析,但如果它确实是重载解析选择的最可行的候选者,那么它就是一个编译器错误。
结果是有道理的,因为移动构造是一种从源对象窃取资源的操作,从而改变它,所以你不应该仅仅通过调用 const
对象就可以做到这一点 std::move
.
std::move(x)
的类型是 Foo const&&
,无法绑定到 Foo&&
。原因与 T const&
无法绑定到 T&
相同。但是,您可以让构造函数采用 Foo const&&
。您很可能无法真正 移动 相应对象的数据,但是,例如,在您的示例中没有数据,即以下代码可以正常工作:
#include <iostream>
struct Foo {
Foo() = default;
Foo(Foo &&) { std::cout << "Move\n"; }
Foo(Foo const&&) { std::cout << "Move const\n"; }
Foo(Foo const &) = delete;
};
int main() {
Foo const x; Foo y(std::move(x));
}