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

时间:2017-11-14 16:56:06

标签: c++ pointers types const auto

This answer声称const自动指针的行为与const常规'相同。 (即非自动)指针,这是我所期望的。

但是,以下代码编译并输出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关键字。有谁知道这是为什么?

3 个答案:

答案 0 :(得分:7)

你似乎对混乱的类型演绎混乱的C ++指针语法感到困惑。使用从右到左的读取顺序读取正常指针声明:

int *             intPtr;           // non-const pointer to non-const int
const int *       intConstPtr;      // non-const pointer to const int
int const *       intConstPtr;      // ditto
int * const       intPtrConst;      // const pointer to non-const int
const int * const intConstPtrConst; // const pointer to const int
int const * const intConstPtrConst; // ditto

所以使用类型演绎

auto autoPtr = &n;            // non-const pointer to non-const int
const auto autoPtrConst = &n; // const pointer to non-const int
auto const autoPtrConst = &n; // ditto

在这种情况下auto将使用&nint *)类型推断,const修饰符将应用于该指针类型,而不是值指针类型指向的类型。如果将auto替换为int *别名,则会得到相同的结果:

using ptr_to_int_t = int *;
const ptr_to_int_t p; // const pointer to non-const int
ptr_to_int_t const p; // ditto

如果您发现指针声明的这种从右到左的阅读顺序令人困惑,您可以利用提供别名模板的Straight declarations库来从左到右阅读顺序声明指针类型:

const ptr<int> p; // const pointer to non-const int
ptr<const int> p; // non-const pointer to const int

答案 1 :(得分:5)

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

const auto * intConstPtr = &n;

这里的auto只是推导到了pointee(int),这是由const限定的。所以这推断为:指向const-int的指针。你也可以写:

const auto * const intConstPtr = &n;

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

答案 2 :(得分:2)

此处,const auto正在转换为int *const,而不是const int*。区别在于它是指向(变量)int常量指针,而不是指向常量int (变量)指针。在这种情况下,这意味着您可以像{I}一样++(*nPtr);,但无法将nPtr更改为指向其他int

要看到这一点,请尝试添加行

int i{ 17 };
nPtr = &i

具有不同int资格的const指针的四种变体,指定时没有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的值。