7

我正在使用 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 中编译时产生以下输出:3 3 2 2

但是用 gcc 编译,结果如下: 3 2 2 2

如果我替换“int number;” 带有“浮点数;” 我进入 VS:2 2 3 3

并使用 gcc:2 2 3 2

我想知道是否有人可以确认这是一个错误,以及是否有人知道可行的解决方法/解决方案。

4

1 回答 1

3

鉴于:

 int number;

这个演员的结果应该是一个prvalue:

const int& recastref_i = (int)number; // this goes wrong if number is int

并且由于您使用的number是const 引用,因此它可以绑定到纯右值,并且它的值应该与检查 的值时,将反映值的变化。numbernumberrecastref_i

Visual Studio 团队建议使用该/Zc:rvalueCast标志来关闭此行为(强调我的):

当指定 /Zc:rvalueCast 选项时,编译器会根据 C++11 标准正确地将右值引用类型识别为强制转换操作的结果。未指定该选项时,编译器行为与 Visual Studio 2012 中的相同。默认情况下,/Zc:rvalueCast 处于关闭状态。为了保持一致性并消除使用强制转换的错误,我们建议您使用 /Zc:rvalueCast。

相反/Za,它将禁用所有在实际场景中可能出现问题的扩展。

从草案 C++ 标准部分5.4 Explicit type conversion (cast notation)1段中说(强调我的):

表达式 (T) cast-expression 的结果是类型 T。如果 T 是左值引用类型或对函数类型的右值引用,则结果是左值;如果 T 是对对象类型的右值引用,则结果是 xvalue;否则结果是纯右值。

于 2015-02-09T03:45:59.113 回答