为何在顶层const被忽略的前提下,auto推导的ptrB不是const int**类型?
关于
auto推导指针类型的疑问解答 先看你的代码:
const int *const ptrA = nullptr; auto *ptrB = &ptrA;
你对const int *const ptrA的拆分是完全正确的:
*const是顶层const——修饰指针ptrA本身,意味着ptrA一旦初始化就不能再指向其他地址const int是底层const——修饰指针指向的对象,意味着通过ptrA不能修改指向的int值
不过你对ptrB类型的推导存在误区,咱们一步步理清楚:
当你取&ptrA时,得到的是一个指向ptrA这个指针的指针。而ptrA的完整类型是const int *const,所以指向它的指针类型自然是const int *const *——也就是说,ptrB是一个指向“指向const int的常量指针”的指针。
你提到的“顶层const会被忽略”,这个规则的适用场景是用对象初始化另一个对象的时候,比如:
const int x = 10; int y = x; // 这里x的顶层const被忽略,y是int类型
但在取指针地址的场景下,顶层const是指针本身的核心属性,绝对不能被忽略——因为ptrA本身是个常量指针,你不能通过ptrB去修改ptrA的指向(比如不能写*ptrB = nullptr;),所以编译器推导ptrB类型时必须保留这个顶层const的约束,也就是const int *const *,而不是const int**。
举个反例就能明白为什么要这么做:如果ptrB是const int**,那理论上你可以做这样的操作:
const int *const ptrA = nullptr; const int** ptrB = &ptrA; // 假设这合法 int* p = nullptr; *ptrB = p; // 这会修改ptrA的指向,但ptrA是顶层const,根本不允许被修改,编译器必然报错
这就是类型安全的体现——编译器通过推导正确的指针类型,防止你做出违反ptrA顶层const约束的操作。
内容的提问来源于stack exchange,提问作者Armando
相关产品推荐
相关产品推荐

