Search code examples
c++c++11overload-resolutionref-qualifier

Difference between l-value ref-qualified member function and unqualified member function?


Is there a difference between l-value ref-qualified member functions and unqualified member functions? If so, what is it?

I.e., are these two ways of declaring func() different?

class Foo
{
  void func();
  void func() &;
};

I don't mean "are they different enough to permit overload resolution," because obviously the above class does not compile when both versions of func() are present. I mean, how and why does the compiler behave differently when & is included versus when it isn't?

There is at least one difference, which is that ref-qualified functions (of either l-value or r-value type) cannot be overloaded with non-ref-qualified functions. From the current standard draft:

Member function declarations with the same name and the same parameter-type-list as well as member function template declarations with the same name, the same parameter-type-list, and the same template parameter lists cannot be overloaded if any of them, but not all, have a ref-qualifier.

...but if this is the only difference, why the restriction? I.e., why can't foo()&& be treated as a valid override of (unqualified) foo()?


Solution

  • They are different.

    Foo foo;
    std::move(foo).func();
    

    will call func() but not func()&.

    Similarly:

    Foo make_foo() { return {}; }
    make_foo().func();
    

    will only work on the void func() signature, not the void func()& signature.

    void func()& means that it only is a valid call on lvalues, not rvalues.