带有移动仪器的源和汇的签名

Signature of source- and sink-functions with move-semantics

本文关键字:移动 仪器      更新时间:2023-10-16

编写源和接收器功能时,我应该使用哪些签名来受益于移动语义,为什么?

T source();
sink(T);
// or
T&& source();
sink(T&&);

好吧,考虑到源创建并返回新对象,T&& source()绝对是垃圾。不要从函数返回对本地变量的引用,此规则适用于RVALUE参考,因为它始终适用于LVALUE参考。

使用sink(T&&)是一种口味问题。它并不是看起来干净和精简的,但另一方面,它更明确地强调了该功能的水槽,并且可以使移动强制性地强制性,即使对于也可以复制的类型也是如此。但是,如果T应该是不可仿制的类型(例如std::unique_ptr),我更喜欢sink(T),因为它看起来更加干净,并且无论如何,该类型的不可仿制性质都明确说明了移动。

,但是在所有情况下,您都会从移动语义中受益,这是他们的优势之一,它们将其融合在一起。因此,无论签名sink具有哪种签名,T t = source();都会像sink(std::move(t));一样移动。仅仅是sink(T)并不能阻止您使用sink(t);调用它,而不是sink(std::move(t));用于可复制类型,这反过来又不会使用移动语义。但这是一个完全不同的问题,因为无论如何,无论何时适当地使用std::move应该是尽快学习的成语。

编辑:是真的,sink(T)在不有效的可移动类型(使用基于值的实现,即std::array)中发挥不佳,因为它需要一个副本(rvalue))参考可能会这样做。即使对于不移动的可移动类型,也比移动更快(尽管这应该可以忽略)。但是话又说回来,我认为,首先,来源和水槽在价值实现的类型方面并不能很好地发挥作用。在这种情况下,T source()无论如何都不是一个好主意(但是,它也不能被上述T&& source()取代)。