这是function template does not recognize lvalue
的后续内容让我们玩下面的代码:
#include <iostream>
template <class T>
void func(T&&) {
std::cout<<"in rvalue\n";
}
template <class T>
void func(const T&) {
std::cout<<"in lvalue\n";
}
int main()
{
double n=3;
func<double>(n);
func(n);
}
打印:
in lvalue
in rvalue
我不明白第二次电话会发生什么。如何编译 解析模板参数?为什么没有歧义?
答案 0 :(得分:13)
当你说func<double>(n)
时,没有参数推断,因为你指定了参数,因此选择在func(double &&)
和func(const double &)
之间。前者不可行,因为右值引用不能绑定到左值(即n
)。
仅func(n)
执行参数推断。这是一个复杂的主题,但简而言之,您有两个可能的候选人:
T = double &: func(T &&) --> func(double &) (first overload)
T = double: func(const T &) --> func(const double &) (second overload)
第一个重载更严格,因为它需要少一个参数值的转换(即从double
到const double
)。
神奇的成分是"reference collapsing",这意味着当T &&
本身就是引用类型时,T
可以是左值引用(具体而言,double & &&
变为{{1}这允许第一次演绎存在)。