我正在使用Visual Studio Express 2013,并且正在尝试学习C++中的不同内容。
我偶然在编译器中发现了一个有趣的错误,当显式类型转换为与引用相同的类型时,它似乎没有创建临时对象。
#include <iostream>
using namespace std;
int main()
{
int number; // float number;
number = 2;
const int& plainref_i = number;
const int& recastref_i = (int)number; // this goes wrong if number is int
const float& plainref_f = number;
const float& recastref_f = (float)number; // this goes wrong if number is float
number = 3;
std::cout << plainref_i << "n";
std::cout << recastref_i << "n";
std::cout << plainref_f << "n";
std::cout << recastref_f << "n";
return 0;
}
这将在 VS 中编译时,产生以下输出:332阿拉伯数字
但是使用 gcc 编译,会产生以下输出:322阿拉伯数字
如果我将"int number;"替换为"float number;";我进入VS:2233
与海湾合作委员会:223阿拉伯数字
我想知道是否有人可以将其确认为错误,以及是否有人知道可行的解决方法/解决方案。
给定:
int number;
此强制转换的结果应为以下值:
const int& recastref_i = (int)number; // this goes wrong if number is int
并且由于您使用的是 const 引用,因此它可以绑定到 prvalue 并且其值应与对 number
的任何更改分离,但 Visual Studio 有一个生成左值而不是 prvalue 的扩展,因此您实际上会收到对 number
的左值引用,这意味着在检查 recastref_i
的值时,任何值的更改都将反映在 number
的值。
Visual Studio 团队建议使用 /Zc:rvalueCast
标志来关闭此行为(强调我的(:
指定/Zc:rvalueCast 选项时,编译器将正确 将右值引用类型标识为强制转换操作的结果 符合C++11标准。当选项不是 指定,编译器行为与 Visual Studio 2012 中的行为相同。 默认情况下,/Zc:rvalueCast 处于关闭状态。 为了一致性和消除 在使用强制转换时出错,建议使用/Zc:rvalueCast。
而不是/Za
,这将禁用所有在实际情况下可能存在问题的扩展。
从草案C++标准部分5.4
显式类型转换(强制表示法(第 1 段说(强调我的(:
表达式 (T( 强制转换表达式的结果是 T 类型。这 如果 T 是左值引用类型或右值,则结果为左值 引用函数类型和 x值(如果 T 是右值引用( 对象类型;否则,结果为 PR值。