Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Const reference qualifier on a member function [duplicate]

I have seen in an anwser there: Is returning by rvalue reference more efficient?

The member function definition:

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

I am familiar with the cv-qualifier (const) on member functions, but not const&.

What does the last const& mean?

like image 644
galinette Avatar asked Apr 11 '14 11:04

galinette


2 Answers

The & is a ref-qualifier. Ref-qualifiers are new in C++11 and not yet supported in all compilers, so you don't see them that often currently. It specifies that this function can only be called on lvalues (and not on 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
}

Combined with the cv-qualifier const, it means that you can only call this member function on lvalues, and those may be const.

like image 65
dyp Avatar answered Nov 07 '22 05:11

dyp


We know that in this code...

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

The highlighted const means that the member function may be called upon a const object. A member function can always be called upon a non-const object regardless of the function's cv-qualification.

So in this code...

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

We should expect that the highlighted & also says something about what kinds of objects this member function is allowed to be called upon. We would be correct; in C++11, this says that the member function may only be called upon lvalues.

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

In the above example, the first overload is invoked on lvalues, and the second overload is invoked on non-const rvalues. Similar to the following more familiar example, with qualifiers applied to ordinary function parameters:

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

It works slightly differently for ordinary parameters though, as in this example, the first overload would accept an rvalue if the second overload were removed.

like image 27
Oktalist Avatar answered Nov 07 '22 05:11

Oktalist