【问题标题】:Overload resolution between const lvalue reference and rvalue referenceconst 左值引用和右值引用之间的重载分辨率
【发布时间】:2017-03-26 16:05:27
【问题描述】:
#include <iostream>
#include <string>

void fnc (const std::string&)
{
    std::cout<<1;
}

void fnc (std::string&&)
{
    std::cout<<2;
}

int main()
{
    fnc ("abc");
}

所有编译器都选择std::string&amp;&amp;版本的fnc,这是合乎逻辑的,因为临时std::string是为引用绑定创建的,但我找不到,它在C++ 14标准中描述的地方。 我在那里找到了一段(3.2):

——标准转换序列 S1 是一个比 S1 更好的转换序列 标准转换序列S2 if

[...]

— S1 和 S2 是引用绑定 (8.5.3),两者都没有引用 声明的非静态成员函数的隐式对象参数 没有引用限定符,并且 S1 将右值引用绑定到 rvalue S2 绑定一个左值引用

但事实并非如此,因为 S1 将右值引用绑定到 左值(“abc”,const char[4] 的左值)。 我在哪里可以找到描述,选择第二个重载?

附:我指的是 C++14 Standard 而不是 C++11,因为我知道 C++11 中有一些缺陷报告,与右值引用绑定相关联。

【问题讨论】:

    标签: c++ c++14 rvalue-reference overload-resolution


    【解决方案1】:

    首先,编译器对"abc" 执行隐式数组到指针的转换,因此"abc" 的类型变为const char*。其次(您可能错过了),const char* 通过const char* non-explicit constructor of std::string(链接中的#5)转换为rvalue std::string。构造的std::string 右值与第二个重载完美匹配,因此选择了第二个重载。

    【讨论】:

      【解决方案2】:

      但事实并非如此,因为 S1 将一个右值引用绑定到一个左值(“abc”,const char[4] 的左值)。

      请注意,"abc"const char[4],而不是 std::string。但是fnc()都以std::string为参数,并且引用不能直接绑定到不同类型的对象。因此首先需要将"abc" 隐式转换为std::string,这是一个临时的,即右值。然后正如标准所说,将选择右值引用重载。

      【讨论】:

        【解决方案3】:

        "abc" 不能直接传递给fnc() 的任一重载。对于它们两者,它必须转换为(右值)std::string。但随后标准中引用的规则明确选择fnc(std::string&amp;&amp;) 而不是fnc(const std::string&amp;)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-05-09
          • 2020-10-17
          • 2017-04-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多