Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么在const对象上调用std::move会在传递给另一个对象时调用复制构造函数?_C++_C++11_C++14 - Fatal编程技术网

C++ 为什么在const对象上调用std::move会在传递给另一个对象时调用复制构造函数?

C++ 为什么在const对象上调用std::move会在传递给另一个对象时调用复制构造函数?,c++,c++11,c++14,C++,C++11,C++14,为什么在传递给另一个对象时,在const对象上调用std::move调用复制构造函数?具体来说,代码 #包括 结构Foo{ Foo()=默认值; Foo(Foo&&x){std::cout使用T const参数调用std::move的结果类型是T const&&,它无法绑定到T&参数。下一个最佳匹配是复制构造函数,它被删除,因此出现错误 明确地deleteing一个函数并不意味着它不能用于重载解析,但是如果它确实是重载解析选择的最可行的候选函数,那么它就是一个编译器错误 结果是有意义的,因为mo

为什么在传递给另一个对象时,在
const
对象上调用std::move调用复制构造函数?具体来说,代码

#包括
结构Foo{
Foo()=默认值;

Foo(Foo&&x){std::cout使用
T const
参数调用
std::move
的结果类型是
T const&&
,它无法绑定到
T&
参数。下一个最佳匹配是复制构造函数,它被删除,因此出现错误

明确地
delete
ing一个函数并不意味着它不能用于重载解析,但是如果它确实是重载解析选择的最可行的候选函数,那么它就是一个编译器错误


结果是有意义的,因为move构造是一种从源对象窃取资源的操作,从而对其进行变异,因此您不应该只通过调用
std::move

类型的
std::move(x)就可以对
const
对象执行此操作
是不能绑定到
Foo&
Foo&&
Foo const&
。其原因与
t const&
不能绑定到
t&
的原因相同。但是,您可以让构造函数接受
Foo const&
。很可能您无法真正移动相应对象的数据,但是,例如,在您的示例中mple没有数据,即以下代码正常工作:

#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)); 
}
#包括
结构Foo{
Foo()=默认值;

Foo(Foo&&){std::cout移动对象的
const
属性没有改变,
Foo-const&&
无法绑定到
Foo&&
,因此编译器尝试访问复制构造函数,但由于复制构造函数被删除而失败。我不擅长移动操作符,但也许你可以对
const
值调用move,但结果是c复制构造函数中只能接受一个值,因此编译器决定调用它。“意思是,我知道std::move会将元素转换为x值”,实际上它不会。它会返回对该项的右值引用。@BenVoigt,有什么区别?[basic.lval]“调用返回类型为对对象类型的右值引用的函数的结果是xvalue。”@BenVoigt
std::move(v)
的结果是转换表达式
v
(它是一个左值,是一个对象,但不是左值引用,因为表达式没有引用类型,[expr]/5)键入
Foo&&
(这是一个xvalue)…我认为说它不把v转换成xvalue是不必要的迂腐,或者完全错误。
#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)); 
}