Определитель задания константы для функции-члена

Я видел в anwser: Является ли возврат ссылкой rvalue более эффективным?

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

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

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

Что означает последний const&?

Ответ 1

& является реф-квалификатором. Ref-qualifiers являются новыми в С++ 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-qualifier const, это означает, что вы можете только вызвать эту функцию-член на lvalues, и они могут быть const.

Ответ 2

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

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

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

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

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

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

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

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

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

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