C++ 中 const 自动指针的行为

Behavior of const auto pointers in C++

This answer 声称 const auto 指针的行为与 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。所以你是说:一个 const 变量,类型为 pointer-to-int。或者,更正式地说:int * const。 pointee 的类型仍然只是 int,非 const 限定,因此修改没有问题。您只是无法更改指针指向的内容。如果你想控制指向类型的常量性,你不能只使用 auto 因为没有意识到它是专门推导出指针类型。所以你必须写:

const auto * intConstPtr = &n;

这里的 auto 只是推导出指针对象 (int),这是 const 所限定的。所以这推导出:指向常量整数的指针。你也可以这样写:

const auto * const intConstPtr = &n;

对于 const-pointer-to-const-int 类型。不过,到那时,您可能应该只使用参考。这就是为什么 const 指针(与指向 const 的指针相反)在 C++ 中并不那么常见,至少在某些代码库中如此(当然有例外)。

在这里,const auto 被转换为 int *const,而不是 const int*。不同之处在于它是指向(变量)int 常量指针,而不是指向常量 int[= 的 (变量)指针56=]。在这种情况下,这意味着您可以照原样执行 ++(*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.
  • 的值