为什么命名变量调用被解析为T &&而不是const T&?

Mir*_*pas 9 c++ c++11

正如标题所说,为什么命名变量调用被解析为T&&而不是const T&函数?

#include <iostream>

template<typename T>
void f(T&& v)
{
    std::cout << "void f(T&& v)" << std::endl;
}

template<typename T>
void f(const T& v)
{
    std::cout << "void f(const T& v)" << std::endl;
}

int main()
{
    int i = 0;

    f(1);
    f(i);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,两个调用都被解析为第一个版本f(),即使i已命名.一种解决方案是添加:

template<typename T>
void f(T& v)
{
    std::cout << "void f(T& v)" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

或将第一个版本更改为:

template<typename T>
typename std::enable_if<!std::is_reference<T>::value, void>::type f(T&& v)
{
    std::cout << "void f(T&& v)" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但我想了解这一决定背后的原因.

Ker*_* SB 14

扣除是T = int &,这意味着f(T &&) == f(int &).重载决策规则([over.ics.rank/13.3.3.2])表示这是一个严格更好的匹配f(int const &).两者都被归类为"完全匹配"(将值绑定到引用),但较少的CV限定引用是首选.

  • @Felics:是的,如果你还有一个小时或八个小时,请阅读重载决议规则.它们包含30页语言标准,但值得了解. (2认同)