Understanding template argument deduction with rvalue/lvalue

别等时光非礼了梦想. 提交于 2019-12-08 16:43:55

问题


This is a followup from function template does not recognize lvalue

Lets play with the following code:

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

It prints:

in lvalue
in rvalue

I don't understand what's happening in the second call. How the compiler resolve the template parameter ? Why isn't there any ambiguity ?


回答1:


When you say func<double>(n), there's no argument deduction, since you specify the argument, and so the choice is between func(double &&) and func(const double &). The former isn't viable, because an rvalue reference cannot bind to an lvalue (namely n).

Only func(n) performs argument deduction. This is a complex topic, but in a nutshell, you have these two possible candidates:

T = double &:    func(T &&)       -->   func(double &)          (first overload)
T = double:      func(const T &)  -->   func(const double &)    (second overload)

The first overload is strictly better, because it requires one less conversion of the argument value (namely from double to const double).

The magic ingredient is the "reference collapsing", which means that T && can be an lvalue reference when T is itself a reference type (specificaly, double & && becomes double &, and that allows the first deduction to exist).



来源:https://stackoverflow.com/questions/22167235/understanding-template-argument-deduction-with-rvalue-lvalue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!