Visual Studio 类型转换时没有创建临时对象?

Visual Studio is not creating temporary object when typecasting?

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

如果我用 "float number;" 替换 "int number;" 我进入 VS: 2个 2个 3个 3

并使用 gcc: 2个 2个 3个 2

我想知道是否有人可以确认这是一个错误,是否有人知道可行的 workaround/solution。

鉴于:

 int number;

这个转换的结果应该是一个纯右值:

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

并且由于您使用的是 const 引用,因此它可以绑定到纯右值,并且它的值应该与对 number 的任何更改分开,但是 Visual Studio 有一个 extension which produces an lvalue instead of a prvalue,所以您实际上接收到对 number 的左值引用,这意味着对 number 的值的任何更改都将在检查 recastref_i.

的值时反映出来

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

When the /Zc:rvalueCast option is specified, the compiler correctly identifies an rvalue reference type as the result of a cast operation in accordance with the C++11 standard. When the option is not specified, the compiler behavior is the same as in Visual Studio 2012. By default, /Zc:rvalueCast is off. For conformance and to eliminate errors in the use of casts, we recommend that you use /Zc:rvalueCast.

/Za 相反,后者将在实际情况下禁用所有 can be problematic 的扩展。

来自 C++ 标准草案部分 5.4 显式类型转换(强制转换符号) 段落 1 说 (强调我的):

The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.