c++ - 参数的值类别在重载决策(或更一般的函数调用处理)的哪一部分中发挥作用?

标签 c++ c++17 overload-resolution value-categories

C++ Templates - The Complete Guide ,在 §C.1 中,读取

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

然后,在 §C.2 中,对(给定论点与可行候选者的相应参数的)可能匹配项进行排序(我的强调):

  • 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 (...). …

现在,由于按值参数的顶级 const 不是函数签名的一部分,我认为第一点括号中的部分是指参数是对表达式类型的引用。如果我的解释是正确的,那就意味着 T const& 参数与 T 类型的参数完美匹配。

毕竟,在 §C.2.2 中,我看到确认:

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, …)

然后本书继续提供一些示例,说明参数的类别值如何确定选择的重载。

但是如果 XX&X const&X&&X const&& 是完美匹配,那么什么时候根据参数的值类别首选其中之一?

这不是重载决议的一部分吗?如果是这样,为什么在上面的几点中根本没有提到值(value)类别?

最佳答案

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

书中有提到,如下引述。特别是,如果您继续进一步阅读,您会看到标题为优化完美匹配C.2.2 部分确实提到了关于区分不同完美匹配的部分:

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.

请注意上面引用示例中的粗体部分。


同样的,它还有下面的例子:

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.

关于c++ - 参数的值类别在重载决策(或更一般的函数调用处理)的哪一部分中发挥作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72929287/

相关文章:

c++ - 可变参数模板作为模板参数 : deduction works with GCC but not with Clang

c++ - "Catch"通过 SendMessage 方法发送的所有消息

c++ - 将参数函数分配给类成员

for vs if vs while 中的 C++17 结构化绑定(bind)声明?

c++ - 'if constexpr'理解错误

具有函数声明/原型(prototype)和定义的 C++ 模板

c++ - 如何将 [[nodiscard]] 属性应用于 lambda?

c++ - 不同编译器之间的名称查找不一致

c++ - 多重继承导致虚假的模棱两可的虚函数重载

c++ - VC++ 2012 中出乎意料的模棱两可的重载解析