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&&
作为参数几乎没有意义。
但是在附录 F(字符串模板类)的 C++ Primer Plus(Stephen Prata 著)一书中,basic_string 的构造函数之一是 basic_string(basic_string&& str) noexcept; !!为什么还是包含在内?
basic_string(basic_string&& str)
构造函数是所谓的 move 构造函数,它是在 C++11 中引入的。它可能比旧的 复制构造函数 basic_string(const basic_string& str)
. 稍微快一点。
【参考方案1】:
GCC 是正确的。来自 3.10 Lvalues and rvalues [basic.lval] 的第 4 段:
类纯右值可以有 cv 限定的类型;非类纯右值总是有 cv 非限定类型。 [...]
诸如fun_ci()
之类的函数调用实际上是纯右值*,因此其类型为int
,而不是const int
。 int&&
比 const int&&
更好匹配,应该通过重载决议来选择。
*:习惯上说*** 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 限定 std::optional::value() 返回 const rvalue 引用?