这是一个有点理论上的问题,但是尽管我对 std::move 有一些基本的了解,但我仍然不确定它是否为该语言提供了一些理论上无法通过超级智能编译器实现的附加功能。我知道这样的代码:
{
std::string s1="STL";
std::string s2(std::move(s1));
std::cout << s1 <<std::endl;
}
是一种新的语义行为而不仅仅是性能糖。 :D 但说实话,我猜在执行 std::move(x) 后没有人会使用 var x。
另外,对于仅可移动的数据(std::unique_ptr、std::thread),如果类型声明为可移动,编译器无法自动执行移动构造和旧变量的清除吗?
同样,这意味着将在程序员后面生成更多代码(例如,现在您可以计算 cpyctor 和 movector 调用,而使用 automagic std::moving 则无法做到这一点)。
No.
但说实话,我猜在执行 std::move(x) 后没有人会使用 var x
绝对不能保证。事实上,很大一部分原因是std::move(x)
is not编译器自动使用是因为,它无法自动决定您是否打算这样做。这是明确定义的行为。
此外,删除右值引用意味着编译器可以自动为您编写所有移动构造函数。这绝对不是真的。 D 有类似的方案,但它完全失败了,因为在许多有用的情况下,编译器生成的“移动构造函数”无法正常工作,但您无法更改它。
它还会阻止完美转发,而完美转发还有其他用途。
委员会犯了许多愚蠢的错误,但右值引用不是其中之一。
Edit:
考虑这样的事情:
int main() {
std::unique_ptr<int> x = make_unique<int>();
some_func_that_takes_ownership(x);
int input = 0;
std::cin >> input;
if (input == 0)
some_other_func(x);
}
哎哟。怎么办?您无法在编译时改变“输入”的值。如果身体some_other_func
and some_func_that_takes_ownership
未知。这是停止问题——你无法证明这一点x
之后使用或未使用some_func_that_takes_ownership
.
D 失败。我答应举个例子。基本上,在 D 中,“移动”是“二进制复制并且不破坏旧的”。不幸的是,考虑一个带有指向自身的指针的类——您可以在大多数字符串类、大多数基于节点的容器、设计中找到它。std::function
, boost::variant
,以及许多其他类似的方便的值类型。指向内部缓冲区的指针将被复制,但是哦,不!指向旧缓冲区,而不是新缓冲区。旧缓冲区被释放 - GG 你的程序。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)