记一次编译错误
我在照着STL 源码刨析写 STL 的时候出现了一个编译错误. 当时的情况是我要用一个派生类的指针给一个基类指针的引用赋值, 类似于:
1 | class Base {}; |
但是编译器报错, 错误信息类似于:
1 | error: cannot bind non-const lvalue reference of type ‘Base*&’ to an rvalue of type ‘Base*’ |
在 C++ 中,
派生类的指针可以直接给基类指针赋值以实现多态的特性.
但是却不可以给基类指针的引用赋值.
这个报错当时令我很困惑.
经过查阅并分析报错信息,
该语句的执行过程应该是首先创建了一个类型为 Base*
的临时值,
用 d
来初始化,
再把这个临时值赋予变量 b
.
因为这个临时值是右值不能给左值赋值,
所有会有这个报错.
这个问题可以用两种方式解决.
第一种方式是通过常量引用可以指向右值实现的.
就是把变量 b
声明为常量指针,
即 Base * const &b = d
,
这样就解决了这个问题.
但是在我当时的代码中不能通过这个方法解决.
因为报错的函数是红黑树的一个迭代函数,
有可能改变 d
的值.
这样的解决方法会复制 d
的值,
使得函数内改变的局部值无法作用到外部的 d
上.
第二种方式是先把 d
做一个强制类型转换再赋值给 b
,
即 Base *&b = (Base*&)d
.
这样就可以在函数中通过修改 b
的值修改 d
.
下面是一个示例代码. 验证两种方法.
1 | class Base {}; |
编译没有报错, 运行得到下面的结果:
1 | add of pd: 0x7ffcdec09978 |
说明方法 1 创建了一个新的指针, 而方法 2 绑定在原来的指针上.