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关键字。有谁知道这是为什么?
答案 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
将使用&n
(int *
)类型推断,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 = &n
或auto const nPtr = &n
。int const *
或const int*
:指向常量int
的可修改指针。您可以更改它指向的int
,但不能使用它来更改int
的值。int const *const
或const int *const
:指向常量int
的常量指针。您无法更改其指向的int
,也无法使用它来更改int
的值。