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