Search code examples
c++c++17overload-resolutionvalue-categories

What part of overload resolution (or more generally of the function call processing) does the value category of the argument play a role in?


C++ Templates - The Complete Guide, in §C.1, reads

  • Overload resolution is performed to find the best candidate. If there is one, it is selected; otherwise, the call is ambiguous.

Then, in §C.2, ranks the possible matches (of a given argument with the corresponding parameter of a viable candidate) like this (my emphasis):

  • Perfect match. The parametere has the type of the expression, or it has a type that is a reference to the type of the expression (possible with added const and/or volatile qualifiers).
  • Match with minor adjustments. This includes, for example, the decay of an array variable to a pointer to its first element or the addition of const to match an argument of type int** to a parameter of type int const* const*.
  • Match with promotion. …
  • Match with standard conversions only. …
  • Match with user-defined conversion. …
  • Match with ellipsis (...). …

Now, since top level const of by-value parameters are not part of the signature of a function, I think that the part in parenthesis in the first point refers to the case that the parameter is a reference to the type of the expression. If my interpretation is correct, that means that a T const& parameter is a perfect match for an argument of type T.

After all, in §C.2.2, I see that confirmed:

For an argument of type X, there are four common parameter types that constitute a perfect match: X, X&, X const&, and X&& (X const&& is also an exact match, …)

And then the book goes on with some example that show how the category value of the argument determines what overload is selected.

But if all of X, X&, X const&, X&&, and X const&& are perfect matches, then when is one of them preferred based on the value category of the argument?

Isn't that part of overload resolution? If so, why the value category is not mentioned at all in the points above?


Solution

  • why the value category is not mentioned at all in the points above?

    It is mentioned in the book as can be seen as quoted below. In particular, if you continue reading further then you'll see that the section C.2.2 titled Refining the Perfect Match does mention the part about distinguishing between different perfect matches:

    With the addition of rvalue references in C++11, another common case of two perfect matches needing to be distinguished is illustrated by the following example:

    struct Value {
    ...
    };
    void pass(Value const&); // #1
    void pass(Value&&);// #2
    void g(X&& x)
    {
        pass(x); // calls #1 , because x is an lvalue
        pass(X()); // calls #2 , because X() is an rvalue (in fact, prvalue)
        pass(std::move(x)); // calls #2 , because std::move(x) is an rvalue (in fact, xvalue)
    }
    

    This time, the version taking an rvalue reference is considered a better match for RVALUES, but it cannot match lvalues.

    Note the bold part in the above quoted example.


    Similarly, it even has the following example:

    void report(int&); // #1
    void report(int const&); // #2
    int main()
    {
        for (int k = 0; k<10; ++k) {
           report(k); // calls #1
        }
        report(42); // calls #2
    }
    

    Here, the version without the extra const is preferred for LVALUES, whereas only the version with const can match RVALUES.