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