Ссылочный квалификатор Const для функции-члена

Я видел в ответе: более эффективно ли возвращение по ссылке rvalue?

Определение функции-члена:

Beta_ab const& getAB() const& { return ab; }

Я знаком с cv-квалификатором (const) на функции-члены, но не const&,

Что делает последний const& имею в виду?

2 ответа

Решение

& является реф-классификатором. Ref-qualifiers являются новыми в C++11 и еще не поддерживаются во всех компиляторах, поэтому в настоящее время вы не часто их видите. Это указывает, что эта функция может быть вызвана только для lvalues ​​(но не для rvalues):

#include <iostream>

class kitten
{
private:
    int mood = 0;

public:
    void pet() &
    {
        mood += 1;
    }
};

int main()
{
    kitten cat{};
    cat.pet(); // ok

    kitten{}.pet(); // not ok: cannot pet a temporary kitten
}

В сочетании с классификатором cv const, это означает, что вы можете вызывать эту функцию-член только для lvalues, и они могут быть const.

Мы знаем, что в этом коде...

Beta_ab const& getAB() const { return ab; }
                       ^^^^^

Выделенный const означает, что функция-член может быть вызвана на const объект. Функция-член всегда может быть вызванаconst объект независимо от cv-квалификации функции.

Итак, в этом коде...

Beta_ab const& getAB() const & { return ab; }
                             ^

Следует ожидать, что выделенный & также говорит кое-что о том, какие объекты разрешено вызывать этой функции-члену. Мы были бы правы; в C++11 это говорит о том, что функция-член может быть вызвана только для lvalue.

Beta_ab const& getAB() const& { return ab; }
Beta_ab &&     getAB() &&     { return ab; }

В приведенном выше примере первая перегрузка вызывается для lvalues, а вторая перегрузка вызывается для не-const rvalues. Аналогичен следующему более знакомому примеру с квалификаторами, примененными к обычным параметрам функции:

void setAB(AB const& _ab) { ab = _ab; }
void setAB(AB &&     _ab) { ab = std::move(_ab); }

Он работает немного по-другому для обычных параметров, хотя, как в этом примере, первая перегрузка приняла бы значение r, если бы вторая перегрузка была удалена.

Другие вопросы по тегам