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

标签 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);
}

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

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

或将第一个版本更改为:

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;
}

但我想了解这个决定背后的原因。

最佳答案

推导为T = int &,即f(T &&) == f(int &)。重载解析规则 ([over.ics.rank/13.3.3.2]) 表明这是比 f(int const &) 更好的匹配。两者都被归类为“完全匹配”(将值绑定(bind)到引用),但 CV 限定较少的引用是首选。

关于c++ - 为什么命名变量调用被解析为 T&& 而不是 const T&?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22585368/

相关文章:

c++ - 声明后在 C++ vector 中分配元素

c++ - 从定义的复制构造函数调用默认(隐式)复制构造函数

c++ - 在异常对象上调用 std::move 是否正确?

使用模板函数的 C++ 模板元编程

C++11:atomic::compare_exchange_weak 是否支持非原始类型?

c++ - std::queue 的基于范围的循环

c++ - 单例 C++ 中的错误

c++ - 如何从 void* 测试类

c++ - 二分查找 - 为什么选择 ceil?

c++ - 通过循环删除 vector 的最后一个元素