作者:手机用户2502885123 | 来源:互联网 | 2022-11-21 10:22
我遇到过这样做的代码:
SomeObject parse (std::istream && input) {....
所述input
参数是一个rvalue参考,这通常意味着该函数取意参数的所有权.这不是这里发生的事情.
该parse
函数将完全消耗输入流,并且它需要rvalue引用,因为然后调用代码将放弃对该属性的所有权,istream
因此这是输入流将不可用的信号.
我认为这是可以的,因为由于parse
函数实际上没有移动对象,所以没有切掉子类型的危险.从parse
观点来看,这基本上表现为普通参考,只有对调用函数有一种可编译的注释,你必须放弃对流的所有权.
这段代码真的安全吗?或者是否有一些被忽视的微妙之处使这变得危险?
1> Lightness Ra..:
一个std::istream
是不可动的,所以这没有实际的好处.
这已经表明事物可能被"修改",而不会混淆暗示你正在转移std::istream
对象的所有权(你没有做,也做不到).
我有种看到原理背后使用此说,流被逻辑地移动,但我认为你必须作出之间"这个东西的所有权被转移"一个区别,"我把这个东西所有权,但我会让你消耗它的所有服务".所有权转移在C++中被很好地理解为一种惯例,而事实并非如此.您的代码用户在必须编写时会想到什么parse(std::move(std::cin))
?
你的方式并不"危险"; 您将无法使用左值引用无法对该左值引用执行任何操作.
只需采用左值参考,就会更加自我记录和传统.
采用"rvalue"参考和移动不一定是彼此结合的.
"*你能给出一个例子*",好吧,问题中的代码......至少在我看来,一个人将*转移输入流的所有权*(通过右值参考意味着)将表明之后没有人应该尝试从中提取,我认为这是一种使用`C++`语法表达意图的巧妙方法.但那只是我的个人意见.
2> François And..:
std::move
只是从一个对象产生一个右值引用,仅此而已.rvalue的性质是这样的,你可以假设在你完成它之后没有其他人会关心它的状态.std::move
然后用于允许开发人员对具有其他值类别的对象做出承诺.换句话说,调用std::move
有意义的上下文相当于说"我保证我不再关心这个对象的状态了".
由于您将使对象基本上无法使用,并且您希望确保调用者不再使用该对象使用右值引用在某种程度上强制执行此期望.它强制调用者对您的函数做出承诺.未能做出承诺将导致编译器错误(假设没有其他有效的重载).如果您实际上是从对象移动并不是唯一的,只是原始所有者同意放弃它的所有权.