Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么命名变量调用解析为T&&;而不是常量T&;?_C++_C++11 - Fatal编程技术网

C++ 为什么命名变量调用解析为T&&;而不是常量T&;?

C++ 为什么命名变量调用解析为T&&;而不是常量T&;?,c++,c++11,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 &

正如标题所说,为什么命名变量调用解析为
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);
}
或将第一个版本更改为:

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;
}
模板
typename std::enable_if::value,void>::类型f(T&&v)
{

std::cout演绎为
T=int&
,意思是
f(T&&==f(int&)
。重载解析规则([over.ics.rank/13.3.3.2])说这是比
f(int const&)
更好的匹配。两者都被归类为“精确匹配”(将值绑定到引用),但首选不太符合CV条件的参考。

一个不太标准的阻碍性答案是在声明中承认:

template<typename T>
void f(T&& v)

迂腐的评论:两个“转换”都有相同的等级,几乎任何直接引用绑定(=没有临时创建),但是将派生类绑定到基类引用是完全匹配的。在[over.ics.rank]中,
T const&
T&
有一个特殊的消歧规则/3@dyp:非常感谢,我重写了。谢谢,我不知道:“简历不太合格的推荐人优先。”@Felics:是的,如果你有一个小时或八个小时的空闲时间,请务必阅读重载解析规则。它们包含30页语言标准,但它们值得知道。注意:两个函数模板之间的偏序规则(仅当参数没有转换顺序->参数转换对于函数模板的两种专门化更好时,才使用“比”)更专门化。啊,您遇到了这样的情况:。简而言之:不要在通用引用上过载;它会给您非常反直觉的结果…:(
template<typename T>
void f(T&& v)
template<typename T>
void f(T&& v)
{
    std::cout << "void f(T&& v)" << std::endl;

    if (std::is_rvalue_reference<decltype(v)>::value)
        std::cout << "rvalue" << std::endl;
    else
        std::cout << "lvalue" << std::endl;

    std::cout << "v = " << std::forward<T>(v) << std::endl;
}