Есть ли реальный вариант использования ссылочных квалификаторов функций?

Недавно я узнал о function's reference qualifiersнапример,

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

Где мне может понадобиться эта функция, есть ли реальный вариант использования этой функции языка?

18

Решение

Есть в основном два варианта использования:

  1. Чтобы обеспечить оптимизированную перегрузку, например, чтобы переместить элемент из временного объекта вместо того, чтобы копировать его.
  2. Предотвращение неправильного использования API. Например, никто не ожидал

    int a = 1 += 2;
    

    работать, и это также приведет к ошибке компиляции. тем не мение

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

    законно, если operator += объявлен как

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

    как обычно бывает. Также у этого есть неприятный побочный эффект предоставления lvalue-ссылки на ваше значение. Плохая идея. Это можно легко предотвратить, объявив оператора

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

Другие решения

Где мне может понадобиться эта функция, есть ли реальный вариант использования этой функции языка?

Пример, который вы показываете, довольно бесполезен, он более полезен, когда у вас есть перегруженная функция, одна версия, которая работает с lvalues, и другая, которая работает с rvalues.

Рассмотрим тип как 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()&&

28

По вопросам рекламы [email protected]