Visual Studio在类型转换时不会创建临时对象? [英] Visual Studio is not creating temporary object when typecasting?

查看:179
本文介绍了Visual Studio在类型转换时不会创建临时对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用Visual Studio Express 2013,并且愚弄了一点想了解C ++中的不同的东西。

I'm using Visual Studio Express 2013 and is fooling around a bit trying to learn about different things in C++.

我偶然发现了一个有趣的错误编译器在显式键入类型转换为与引用相同类型时,它似乎不创建一个临时对象。

I stumbled upon an interesting bug in the compiler where it doesn't seem to create a temporary object when explicitly type casting to the same type as the reference.

#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

This will when compiled in VS, results in the following output: 3 3 2 2

但是使用gcc编译,会产生以下输出:
3
2
2
2

But compiled with gcc, results in the following output: 3 2 2 2

如果我替换int number;带浮点数我在VS:
2
2
3
3

If I replace "int number;" with "float number;" I get in VS: 2 2 3 3

和gcc:
2
2
3
2

and with gcc: 2 2 3 2

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

I'm wondering if anyone can confirm this as a bug and if anyone knows of a feasible workaround/solution.

推荐答案

给定:

 int number;

此转换的结果应为prvalue:

The results of this cast should be a prvalue:

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

就会出错,因为你使用的是const引用, prvalue及其值应与 number 的任何更改分离,但Visual Studio有扩展,生成一个左值而不是prvalue ,所以你实际上收到一个左值引用 number 这意味着值的任何变化到检查 recastref_i 的值时,会反映出

and since you are using const reference then it can bind to the prvalue and its value should be divorced from any changes to number but Visual Studio has an extension which produces an lvalue instead of a prvalue, so you actually receive an lvalue reference to number which means any changes in value to number will be reflected when checking the value of recastref_i.

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

The Visual Studio team recommends using the /Zc:rvalueCast flag to turn off this behavior (emphasis mine):


当指定/ Zc:rvalueCast选项时,编译器正确地
标识一个右值引用类型作为转换操作的结果
根据C ++ 11标准。当选项不是
时,编译器的行为与Visual Studio 2012中的相同。
默认情况下,/ Zc:rvalueCast关闭。 为了符合并消除使用强制转换的
错误,我们建议您使用/ Zc:rvalueCast。

而不是 / Za ,这将禁用所有扩展在实际情况下可能有问题

as opposed to /Za which will disable all extensions which can be problematic in practical scenarios.

从草案C ++标准部分 5.4 段落 的显式类型转换>

From the draft C++ standard section 5.4 Explicit type conversion (cast notation) paragraph 1 which says (emphasis mine):


表达式(T)cast-expression的结果是类型T.如果T是一个左值引用,
结果是一个左值类型或右值
对函数类型的引用和x值,如果T是对值类型的右值引用
; 否则结果为prvalue。

这篇关于Visual Studio在类型转换时不会创建临时对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆