使用右值引用的重载分辨率不一致

时间:2014-07-31 14:35:44

标签: c++ c++11

我对重载分辨率的理解是'T&&'通常比'const T&'更好地匹配。但是,我看到编译器之间存在一些不一致的行为:这个简单的例子:

#include <iostream>

void Func(const double& a)
{
    (void)a;
    std::cout << "[lvalue]\n";
}

void Func(double&& a)
{
    (void)a;
    std::cout << "[rvalue]\n";
}

template <typename T>
void TFunc(T&& a)
{
    Func(a);
}

int main ()
{
    TFunc(5.5f);

    return 0;
}

Clang 3.2将打印 [rvalue] 。但是,VS2013 32位/ 64位编译器将打印 [左值] 。如果我将“5.5f”更改为“5.5”,则两个编译器都将打印 [左值]

我能理解为什么VS编译器会选择'const double&amp;'版本,因为我没有std :: forward调用以保留'&amp;&amp;'参数。但是,我仍然不明白是什么让clang认为'&amp;&amp;&amp;'超载是更好的选择。

为什么在double转换中添加隐式浮点会影响clang中的行为?谁是对的?

1 个答案:

答案 0 :(得分:8)

当您使用5.5f拨打电话时,T是浮动的,Func电话有效地变为Func(double(a))。该参数是临时的,因此应该选择rvalue重载。

当您使用5.5致电时,T为双倍,并且在调用Func(a)时不会创建临时值。命名变量不能绑定到右值引用,因此左值超载是唯一的选择。

MSVC有一个长期的错误,允许临时绑定到非const左值引用。这就是为什么即使在第一种情况下它也错误地选择左值超载。尝试使用/Za进行编译(禁用语言扩展) - 我相信它会符合clang的行为。