Недавно я узнал о function's reference qualifiers
, например.
struct foo
{
void bar() {}
void bar1() & {}
void bar2() && {}
};
Где мне может понадобиться эта функция, есть ли реальный вариант использования этой языковой функции?
Недавно я узнал о function's reference qualifiers
, например.
struct foo
{
void bar() {}
void bar1() & {}
void bar2() && {}
};
Где мне может понадобиться эта функция, есть ли реальный вариант использования этой языковой функции?
В основном есть два варианта использования:
Предотвращение неправильного использования API. Например, никто не ожидал
int a = 1 += 2;
работать, и это также вызовет ошибку компиляции. Однако
string b = string("foo") += "bar";
является допустимым, если operator +=
объявлен как
string & operator += (string const & o);
как это обычно бывает. Также это имеет неприятный побочный эффект предоставления ссылки lvalue на ваше значение rvalue. Плохая идея. Этого можно легко избежать, объявив оператор как
string & operator += (string const & o) &;
Где мне может понадобиться эта функция, есть ли реальный вариант использования этой языковой функции?
Показанный вами пример довольно бесполезен, он более полезен, когда у вас есть перегруженная функция, одна версия которой работает с lvalue, а другая — с rvalue.
Рассмотрим тип, немного похожий на std::stringstream
, который владеет строкой и возвращает ее по значению. Если объект является значением r, он может перемещать строку вместо ее копирования.
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()&&
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
объекта. - person Tomilov Anatoliy   schedule 20.01.2015