dnf*_*nfs 7 c++ casting const-reference temporary-objects visual-studio-2013
我正在使用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;
}
Run Code Online (Sandbox Code Playgroud)
这将在VS中编译时产生以下输出:3 3 2 2
但是使用gcc编译,会产生以下输出:3 2 2 2
如果我替换"int number;" 用"浮点数"; 我进入VS:2 2 3 3
和gcc:2 2 3 2
我想知道是否有人可以确认这是一个错误,如果有人知道一个可行的解决方法/解决方案.
鉴于:
int number;
Run Code Online (Sandbox Code Playgroud)
此转换的结果应该是纯右值:
const int& recastref_i = (int)number; // this goes wrong if number is int
Run Code Online (Sandbox Code Playgroud)
并且由于您使用的是 const 引用,因此它可以绑定到纯右值,并且其值应该与任何更改分开,number但 Visual Studio 有一个扩展可以生成左值而不是纯右值,因此您实际上会收到一个左值引用,number这意味着任何number检查 的值时,将反映 的值的变化recastref_i。
Visual Studio 团队建议使用该/Zc:rvalueCast标志来关闭此行为(重点是我的):
当指定 /Zc:rvalueCast 选项时,编译器根据 C++11 标准正确地将右值引用类型识别为强制转换操作的结果。未指定该选项时,编译器行为与 Visual Studio 2012 中相同。默认情况下,/Zc:rvalueCast 处于关闭状态。为了保持一致性并消除使用强制转换时的错误,我们建议您使用 /Zc:rvalueCast。
相反/Za,这将禁用所有在实际场景中可能出现问题的扩展。
从 C++ 标准草案的5.4 “显式类型转换(转换符号)”第1段中可以看出(重点是我的):
表达式 (T) 强制转换表达式的结果为 T 类型。如果 T 是左值引用类型或对函数类型的右值引用,则结果是左值;如果 T 是对对象类型的右值引用,则结果是 xvalue;否则结果是纯右值。
| 归档时间: |
|
| 查看次数: |
303 次 |
| 最近记录: |