对引用进行类型转换
Type conversions on references
我发现const引用有一种意外行为:
#include <iostream>
using namespace std;
template <typename T>
void myfunction() {
T b = 30;
const int &i = b;
cout << "Before change: " << i << endl;
b = 33;
cout << "After change: " << i << endl;
}
int main() {
cout << "int" << endl;
myfunction<int>();
cout << endl;
cout << "double" << endl;
myfunction<double>();
}
这给出了以下结果:
int
Before change: 30
After change: 33
double
Before change: 30
After change: 30
我知道在第二种情况下;我没有引用b,因为它是双精度的,但引用了一个临时对象。这也是为什么在更改b时i的值没有改变的原因。
但为什么这样的行为是被允许的呢?在我看来,这是违反直觉的。只使用const int i = b
有什么性能优势吗?
你通常可以想到
const int &i = b;
作为
int const* const p_i = &b;
自动取消引用,比如(但不要太当真!)
#define i (*p_i)
第一个const
表示不能通过指针/引用更改b
。但你可以通过其他方式改变它。然后,您通过看到的指针/引用发生了更改。
在b
类型为double
的情况下,引用不能直接引用它。然后,您得到的是从double
转换而来的临时int
,其生存期延长到引用的生存期(事物的指针视图有点崩溃!)。在这种情况下,对原始文件所做的更改不会反映在引用所指的临时文件中。
顺便说一句,这种混叠(两种或多种引用相同事物的方式,具有不同的限制)原则上是通过引用const
来传递的问题。令人高兴的是,这在实践中并不是什么大问题。事实上,我从来没有遇到过这种情况,除了创建一些愚蠢的例子来教授技术可能性。
关于
"但为什么这样的行为是被允许的呢?
…这询问了两个问题:
绑定到引用时临时的生存期扩展。
从
double
到int
的隐式转换。
当我问Bjarne延长寿命的理由时,在过去,每个人(包括Bjanne)都使用comp.lang.c++Usenet组,他回答说,这主要是为了规则的一致性。
从double
到int
,以及通常从任何内置数字类型到另一种内置数字类型的潜在且通常破坏信息的隐式转换,在旧的C时代就存在。在C++11及更高版本中,您可以通过使用braked初始化程序来限制允许的转换。因此,如果你写
const int &i = {b};
…那么对于b
类型为double
的情况,代码就不会编译,因为这将是缩小转换。
当然,这对例如键入short
(不再是缩小转换范围)没有帮助,但它有一点帮助。
在这种情况下,我不同意这违反直觉。
考虑以下示例
struct A
{
A( double x ) : x ( x ) {}
double x;
};
const A &ra1 = A( 10.0 );
const A &ra2 = 10.0;
我想你们不会反对这些引用声明。它们是直观的。
现在只需将类名A
替换为类型int
,就可以得到
const int &ri1 = int( 10.0 );
const int &ri2 = 10.0;
在我看来,这是有逻辑的。
例如,MS VC++为最后一个声明生成警告
警告C4244:"initializing":从"double"转换为"const"int',可能的数据丢失
至于性能优势,您应该仔细查看生成的对象代码。它可以以这样的方式发生,即对于这两个声明,编译器生成相同的对象代码。
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++中的双指针类型转换
- 逐位操作的隐式类型转换
- 模板中的类型转换
- 在 C++(和 C)中进行类型转换时明显不一致
- 通过引用传递参数时C++类型转换
- C++ 类型转换基础 PTR 到派生 PTR 保存在引用类中
- 自定义类型转换运算符在转发引用上调用时不起作用(当对象按值传递时有效)
- 如何将引用类型转换为值类型
- 将运算符类型转换为除某些引用之外的任何算术类型
- 引用 void* 的隐式类型转换
- 在C++中,为什么对派生类型的引用进行强制转换
- 对引用进行类型转换
- c++中的类型转换和引用
- 引用类型转换中的c++虚函数
- 与强制类型转换指针相比,在dynamic_cast中使用强制类型转换引用
- 为什么将类型转换为指针然后解引用可以工作?
- 带和不带引用的指针类型转换
- 用于 lambda 和函数的常见类型转换,稍后要引用