为什么没有从指针到引用的隐式转换?

时间:2019-05-20 07:32:41

标签: c++ c++03

#include <iostream>
using namespace std;

int main() {
    int x = 5;
    int* y = &x;
    int& z = y;
    return 0;
}

对于此代码,编译器在int& z = y;上给出错误消息:

./example.cpp: In function 'int main()':

./example.cpp:7:11: error: invalid conversion from 'int*' to 'int' [-fpermissive]

    7 |  int& z = y;

      |           ^

      |           |

      |           int*

./example.cpp:7:11: error: cannot bind rvalue '(int)y' to 'int&'

为什么?我知道错误的原因,并且知道如何解决,我很好奇为什么编译器无法隐式执行转换,对我而言,使指针和引用引用到我的意图似乎微不足道。相同的内存位置。我有什么想念的极端情况吗?

3 个答案:

答案 0 :(得分:5)

C ++源自隐式转换的错误由来已久。看看Stephen Dewhurst的书“ C ++ Gotchas”;最长的一章是关于转化的。这个主题实际上充满了陷阱,我们应该高兴地明确指出以上内容。话虽这么说...

  

我想念一些极端的情况吗?

考虑这样的过载设置:

void f(void *n);
void f(int& n);

以及将指针隐式转换为引用的映像。以下通话

int n = 42;

f(&n);

将是模棱两可的,因为两个转换都被认为是等效的。这会混淆不必要的内容。

另一个例子是对指针的引用。不一定您会经常做的事情,但这是有效的:

int n = 42;
int* ptr = &n;

int*& refToPtr = ptr;

使用引用转换的隐式指针,以上内容将针对

进行编译
int& refToPtr = &n;

即使您的意思有所不同,再说一遍,在这里放宽一些对于防止此类错误也是一件好事。

答案 1 :(得分:1)

您应该将C ++引用视为别名而不是指针。这与看起来更像指针的Java引用不同。然后,编译器消息就很清楚了:别名对象应该是一个int,而您尝试引用一个int *。

有关参考的更多信息:https://isocpp.org/wiki/faq/references

答案 2 :(得分:1)

指针可以为空,引用不能为空。

注意:您不能这样做

int* ptr = nullptr;
int& ref = *ptr; // dereferencing a nullptr is UB

如果C ++允许隐式转换以引用指针,则意味着它隐式地引用了一个指针,该指针可以是UB。