Visual Studio 在类型转换时不会创建临时对象



我正在使用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值。

最新更新