为什么没有从指针到引用的隐式转换?
Why there is no implicit conversion from pointer to reference?
#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&'
为什么?我知道错误的原因,也知道如何修复它,我很好奇为什么编译器无法隐式执行转换,对我来说,让指针和引用指向相同的内存位置。有没有我遗漏的极端情况?
C++ 由隐式转换引起的错误由来已久。看看 Stephen Dewhurst 的书 "C++ Gotchas";最长的一章是关于皈依的。这个话题字面上充满了陷阱,我们应该很高兴上面必须明确地打出来。话虽这么说...
Are there any corner cases I am missing?
考虑这样的重载集:
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;
同样,即使您的意思有所不同,再次强调,在这里不那么宽容是防止此类错误的好方法。
您应该将 C++ 引用视为别名而不是指针。这与看起来更像指针的 Java 引用不同。那么编译器的消息就非常清楚了:别名对象应该是一个 int 而你尝试引用一个 int*.
有关参考资料的更多信息:https://isocpp.org/wiki/faq/references
指针可以为空,引用不能。
注意:你不能这样做
int* ptr = nullptr;
int& ref = *ptr; // dereferencing a nullptr is UB
如果 C++ 允许对指针的引用进行隐式转换,这意味着它将隐式引用一个指针,它可以是 UB。
#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&'
为什么?我知道错误的原因,也知道如何修复它,我很好奇为什么编译器无法隐式执行转换,对我来说,让指针和引用指向相同的内存位置。有没有我遗漏的极端情况?
C++ 由隐式转换引起的错误由来已久。看看 Stephen Dewhurst 的书 "C++ Gotchas";最长的一章是关于皈依的。这个话题字面上充满了陷阱,我们应该很高兴上面必须明确地打出来。话虽这么说...
Are there any corner cases I am missing?
考虑这样的重载集:
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;
同样,即使您的意思有所不同,再次强调,在这里不那么宽容是防止此类错误的好方法。
您应该将 C++ 引用视为别名而不是指针。这与看起来更像指针的 Java 引用不同。那么编译器的消息就非常清楚了:别名对象应该是一个 int 而你尝试引用一个 int*.
有关参考资料的更多信息:https://isocpp.org/wiki/faq/references
指针可以为空,引用不能。
注意:你不能这样做
int* ptr = nullptr;
int& ref = *ptr; // dereferencing a nullptr is UB
如果 C++ 允许对指针的引用进行隐式转换,这意味着它将隐式引用一个指针,它可以是 UB。