3

正如我所看到的,一般规则是根本不从函数返回 r 值引用(罕见的特殊情况除外)。但是类方法呢?

std::optional<T>::operator*()C++ 标准库中有一个从类的 r-value ref-qualified 方法(和类std::optional<T>::value()的方法)返回 r-value 引用的示例std::optional<T>。请参阅C++17 标准的23.6.3 类模板可选 [optional.optional]23.6.3.5 Observers [optional.observe]部分:

// 23.6.3.5, observers

constexpr T&& operator*() &&;
constexpr const T&& operator*() const&&;
constexpr T&& value() &&;
constexpr const T&& value() const&&;
4

1 回答 1

4

一般考虑类成员访问。假设我们有这样的类型:

struct A {
  int x;
};

现在让我们取一个 type 的对象A

A a;

现在表达式(a)是一个左值,成员访问(a).x也是一个左值。但是表达式std::move(a)是一个右值(实际上是一个 xvalue),std::move(a).x现在也是一个右值(实际上是一个 xvalue)。这是核心语言中成员访问的行为。

现在,用户定义类型提供模仿核心语言行为的用户定义行为是有意义的。我们可以通过使用 ref 限定的成员函数来做到这一点,它可以区分实例是左值还是右值。当成员函数的目的是提供对子对象的访问时,当实例是右值时,将该子对象作为右值(特别是 xvalue)返回是合理的。

您可能指的一般建议是,您不应该随机返回对某些您无法控制的任意对象的右值引用。在这种情况下,返回副本通常要好得多,这样您的函数就可以独立于无关对象生命周期的上下文假设来使用。但是当您谈论成员函数并且所讨论的对象是类实例时,您有更多的控制权,并且返回 xvalues 可能是有用的工具。

这里的一个元教训是,在 C++ 中询问“<特定语法 X> 是否是好的实践”并不总是有用的。C++ 为你提供了很多工具,有时你不得不在上下文中谈论设计。

于 2018-01-28T16:36:40.447 回答