const rvalue 编译器的区别

Posted

技术标签:

【中文标题】const rvalue 编译器的区别【英文标题】:Const rvalue compiler difference 【发布时间】:2012-08-28 13:52:57 【问题描述】:

考虑这段代码:

#include <iostream>


void f(int&& i)

    std::cout << "f(int&&)\n";


void f(const int&& i)

    std::cout << "f(const int&&)\n";



int fun_i()

    return 0;


const int fun_ci()

    return 0;


int main()

    f(fun_i());
    f(fun_ci());

如果我用 MSVC 2012 编译它,输出是:

f(int&&)
f(const int&&)

如果我用 GCC 4.7 编译,输出是:

f(int&&)
f(int&&)

哪个是正确的?

(如果我删除 f 的第二个定义,程序将无法在 MSVC 2012 下编译,但在 GCC 4.7 下可以编译。)

【问题讨论】:

注意:将const&amp;&amp; 作为参数几乎没有意义。 但是在附录 F(字符串模板类)的 C++ Primer Plus(Stephen Prata 著)一书中,basic_string 的构造函数之一是 basic_string(basic_string&& str) noexcept; !!为什么还是包含在内? basic_string(basic_string&amp;&amp; str) 构造函数是所谓的 move 构造函数,它是在 C++11 中引入的。它可能比旧的 复制构造函数 basic_string(const basic_string&amp; str). 稍微快一点。 【参考方案1】:

GCC 是正确的。来自 3.10 Lvalues and rvalues [basic.lval] 的第 4 段:

类纯右值可以有 cv 限定的类型;非类纯右值总是有 cv 非限定类型。 [...]

诸如fun_ci() 之类的函数调用实际上是纯右值*,因此其类型为int,而不是const intint&amp;&amp;const int&amp;&amp; 更好匹配,应该通过重载决议来选择。

*:习惯上说*** cv 限定符对于非类返回类型会被忽略。

【讨论】:

谢谢你,卢克!我通过用代码中的类替换 'int' 来验证你写的内容,然后两个编译器提供相同的输出:首先没有 'const',然后使用 'const'。 @ClausTøndering 您也可以尝试使用 xvalue,例如您为非const 变量和const 变量传入std::move(i)【参考方案2】:

我倾向于说 gcc 似乎在做正确的事情,基于它发出的警告:

stieber@gatekeeper:~$ g++ -std=c++11 -Wignored-qualifiers Test.cpp
Test.cpp:20:18: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]

【讨论】:

以上是关于const rvalue 编译器的区别的主要内容,如果未能解决你的问题,请参考以下文章

为 const 引用和 rvalue 引用编写重载

为啥 const rvalue 限定 std::optional::value() 返回 const rvalue 引用?

RValue 由啥构成?

const和宏定义的区别!!!

const和defin区别

C++中加const与不加const的区别