C++中常量自动指针的行为

Behavior of const auto pointers in C++

本文关键字:指针 常量 C++      更新时间:2023-10-16

这个答案声称const自动指针的行为与const"regular"(即非自动)指针相同,这正是我所期望的。

但是,以下代码编译并输出100:

int n{ 99 };
const auto nPtr = &n;
++(*nPtr);
std::cout << n << 'n';

为了更深入地挖掘,我检查了所有4种指针的类型,这是我得到的结果:

代码

int n{ 99 };
int* intPtr = &n;
const int* intConstPtr = &n;
auto autoPtr = &n;
const auto autoConstPtr = &n;
std::cout << "intPtr: " << typeid(intPtr).name() << 'n';
std::cout << "intConstPtr: " << typeid(intConstPtr).name() << 'n';
std::cout << "autoPtr: " << typeid(autoPtr).name() << 'n';
std::cout << "autoConstPtr: " << typeid(autoConstPtr).name() << 'n';

输出

intPtr:int*__ptr64

intConstPtr:int const*__ptr64

autoPtr:int*__ptr64

autoConstPtr:int*__ptr64

因此编译器似乎完全忽略了带有自动指针的const关键字。有人知道为什么会这样吗?

当您编写const auto时,您会说:使推导变量的类型const。推导变量的类型为int *,即pointer-to-int。所以你说的是:一个常量变量,类型为pointer-to-int。或者,更正式地说:int * const。指针对象的类型仍然只是int,非常量限定,所以修改是没有问题的。你不能改变指针指向的内容。如果你想控制被指向类型的常量,你不能只使用auto,因为你不知道它是专门推导到指针类型的。所以你必须写:

const auto * intConstPtr = &n;

这里的auto只是推导到pointee(int),它是由const限定的。因此,这推导为:pointer-to-const-int。你也可以写:

const auto * const intConstPtr = &n;

对于类型const-pointer-to-const-int。不过,在这一点上,你可能只应该使用一个参考。这就是为什么const指针(与指向const的指针相反)在C++中并不常见,至少在一些代码库中是这样(当然也有例外)。

这里,const auto被转换为int *const,而不是const int*。不同之处在于,它是指向(变量)int常量指针,而不是指向常量int。在这种情况下,这意味着您可以执行++(*nPtr);,但不能将nPtr更改为指向不同的int

要查看此信息,请尝试添加行

int i{ 17 };
nPtr = &i

具有不同const资格的int指针的四种变体(在没有auto的情况下指定)是:

  • int*:指向可修改int的可修改指针。您可以更改它指向的int,也可以使用它来更改该int的值。这就是只需auto nPtr = &n即可获得的结果
  • int *const:指向可修改int的固定指针。它将始终指向相同的int,但您可以使用它来更改该int的值。这就是const auto nPtr = &nauto const nPtr = &n的结果
  • int const *const int*:指向常量int的可修改指针。您可以更改它指向的int,但不能使用它来更改该int的值
  • int const *constconst int *const:指向常量int的常量指针。您不能更改它指向的int,也不能使用它来更改该int的值