18

最近我了解到function's reference qualifiers,例如

struct foo
{
    void bar() {}
    void bar1() & {}
    void bar2() && {}
};

在我可能需要此功能的地方,此语言功能是否有任何实际用例?

4

2 回答 2

29

在我可能需要此功能的地方,此语言功能是否有任何实际用例?

您展示的示例非常无用,当您有一个重载函数时,它更有用,一个对左值操作的版本和一个对右值操作的版本。

考虑一个有点像的类型std::stringstream,它拥有一个字符串并按值返回它。如果对象是右值,它可以移动字符串而不是复制它。

class StringBuilder
{
public:
  std::string get() const& { return m_str; }
  std::string get() && { return std::move(m_str); }

private:
  std::string m_str;
};

这意味着当您StringBuilder从函数返回 a 并希望从中取出字符串时,您不需要副本:

std::string s = buildString().get();

更一般地说,给定一个函数f(const X&),如果用 重载它是有用的f(X&&),那么给定一个成员函数,将它更改为并重载它X::f()可能是有用的X::f() const&X::f()&&

于 2015-01-19T14:04:22.527 回答
17

基本上有两种用途:

  1. 提供优化的重载,例如将成员移出临时对象而不必复制它。
  2. 防止滥用 API。例如,没有人会期望

    int a = 1 += 2;
    

    工作,这也会导致编译错误。然而

    string b = string("foo") += "bar";
    

    如果operator +=声明为是合法的

    string & operator += (string const & o);
    

    通常情况下。这也具有为您的右值提供左值引用的令人讨厌的副作用。馊主意。这可以通过将操作符声明为

    string & operator += (string const & o) &;
    
于 2015-01-19T15:22:09.557 回答