const auto和auto const如何应用于指针?

9

我试着编写一些代码,想知道在使用auto时,C++中的const限定符如何应用于指针类型。

int main()
{
  int foo = 1;
  int bar = 2;

  //Expected: const int * ptr_to_const_int = &foo;
  const auto ptr_to_const_int = &foo;

  //Expected: int * const const_ptr_to_int = &foo;
  auto const const_ptr_to_int = &foo;


  *ptr_to_const_int = 3; //Thought this would error
  //ptr_to_const_int = &bar; This does error.
  *const_ptr_to_int = 3;

  return 0;
}

我知道有一道类似的问题询问它们是否相同,我更具体地询问的是在这里应用于终点指针类型的规则是什么。


6
对于别名,它的作用方式是相同的:using T = int *; const T -> int *const - HolyBlackCat
3
const autoauto const 是相同的类型。示例 - BiagioF
auto 使用 模板参数推导 的规则。 - wally
2个回答

12
在这个示例中,const被应用于auto所推断的任何内容,这意味着两种用法都会产生一个int * const类型的对象,因为auto本身推断出int *。你所想象的排序是基于你是否写成auto constconst auto,但实际上并没有发生,就像int constconst int是一样的。
更容易理解的方法可能是尝试以下操作:
template<typename T>
using pointer = T*;

pointer<int> ptr_to_int = new int;
const pointer<int> const_ptr_to_int = new int;
pointer<const int> ptr_to_const_int = new int;
const pointer<const int> const_ptr_to_const_int = new int;

pointer<int> const const_ptr_to_int2 = new int;
pointer<int const> ptr_to_const_int2 = new int;
pointer<const int> const const_ptr_to_const_int2 = new int;

pointer<int const> const const_ptr_to_const_int3 = new int;

在此示例中,只有名称末尾数字不同的变量是等效类型,就C++而言。请注意,更改const出现的位置不会影响推断的类型。这是因为“从右到左”阅读以确定如何声明类型的规则基于原始类型的编写方式:一旦使用了这样的结构(或者,如您所观察到的那样,auto),规则就变得简单得多。
我的直觉是,由于您的问题暗示您需要对类型系统进行这种细粒度控制,因此应该像我在这里展示的那样,在pointer<T>上使用usingtypedef,并使用它来声明您的类型,因为这样一眼就可以知道const pointer<int>是什么,而不是看到int *const是什么。特别是因为它可以防止愚蠢的错误,比如这样的错误:
int * a_ptr, b_ptr, c_ptr; //Oops! We meant b_ptr and c_ptr to also be pointers, but
//they ended up being regular ints!

pointer<int> a_ptr, b_ptr, c_ptr; //All of these are pointers, as we expected them to be
< p > auto 技术上也可以解决这个问题,但正如你在示例中展示的那样,你仍然不确定 const 是被应用于指针本身还是它所指向的对象,而在这种情况下,就没有更多的歧义了。


3

当存在*时,位置很重要。

  1. *之前放置const会使值变为常量。
  2. *之后放置const会使地址变为常量。
  3. *之前/之后放置const会使值和地址都变为常量。

为了更好地理解,我提供了一些可能的autoconst*使用组合。

    int main() {
        auto i = 2;               // int
        const auto j = 10;        // const int  
        
        // j = 20;                // Error: value is const

        const auto a = &i;        // int * const
        // a = &j;                // Error: addr is const
        *a = 4;                   // OK (value is NOT const)

        const auto* b = &i;       // const int *
        // *b = 4;                // Error: value is const
        b = &j;                   // OK (addr is NOT const)

        auto* const c = &i;       // const int *
        *c = 4;                   // OK (value is NOT const)
        // c = &j;                // Error: addr is const

        const auto* const d = &i; // const int * const
        // *d = 4;                // Error: Both value & addr are const
        // d = &j;                // Error: Both value & addr are const
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接