最近我了解了关于函数的引用限定符,例如。
在哪些情况下我可能需要这个功能?这个语言特性有没有实际的用例呢?
struct foo
{
void bar() {}
void bar1() & {}
void bar2() && {}
};
在哪些情况下我可能需要这个功能?这个语言特性有没有实际的用例呢?
struct foo
{
void bar() {}
void bar1() & {}
void bar2() && {}
};
在我可能需要这个特性的情况下,这个语言特性有什么真正的用例吗?
你展示的例子相当无用,当你有一个重载函数时,它更有用,其中一个版本操作 lvalue,另一个版本操作 rvalue。
考虑一种类型,类似于 std::stringstream
,它拥有一个字符串并按值返回它。如果对象是一个 rvalue,则可以移动字符串而不是复制它。
class StringBuilder
{
public:
std::string get() const& { return m_str; }
std::string get() && { return std::move(m_str); }
private:
std::string m_str;
};
这意味着当您从函数返回一个StringBuilder
并想要获取其中的字符串时,您不需要复制:
std::string s = buildString().get();
更一般地,假设有一个函数f(const X&)
,如果使用f(X&&)
重载它会很有用,那么对于一个成员函数X::f()
,将其改为X::f() const&
并将其与 X::f()&&
进行重载可能是有用的。
基本上有两种用途:
防止API的误用。例如,没有人会期望
int a = 1 += 2;
继续工作将导致编译错误。
string b = string("foo") += "bar";
operator +=
如果被声明为
string & operator += (string const & o);
通常情况下就是这样。此外,这会产生一个让您的rvalue具有左值引用的不良副作用。这是个坏主意。可以通过将运算符声明为来轻松避免这种情况
string & operator += (string const & o) &;
struct foo { operator std::string () const & { return s; } operator std::string () && { return std::move(s); } std::string s; };
。因此,foo func() { return {"string"s}; } ... std::string s = foo();
不会涉及非必要的拷贝和销毁操作,可以避免对非空std::string
对象的操作。 - Tomilov Anatoliy