【问题标题】:How does const auto and auto const apply to pointers?const auto 和 auto const 如何应用于指针?
【发布时间】:2022-04-26 18:36:09
【问题描述】:

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

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;
}

我意识到有一个类似的问题询问它们是否相同,我更具体地说是问这里适用于推断结束指针类型的规则是什么。

【问题讨论】:

标签: c++ c++11


【解决方案1】:

在这个例子中,const 被应用到任何auto 的推导,这意味着这两种用法都会导致int * const 类型的对象,因为auto 本身就是推导int *。你想象的排序发生在你写的是auto const还是const 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&lt;T&gt; 上使用 usingtypedef在这里,并使用它来声明您的类型,因为一目了然地知道const pointer&lt;int&gt; 是什么比查看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

auto 在技术上也解决了这个问题,但是正如您在示例中所展示的,const 是应用于指针本身还是它指向的对象仍然是模棱两可的,而在这种情况下,不再有歧义。

【讨论】:

    【解决方案2】:

    *!!的地方很重要。

    1. const 放在* 之前会使值变为常量。
    2. const 放在 * 之后会使 addr 变为常量。
    3. * 之前/之后放置 const 会使 value 和 addr 都变为 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
        }
    

    【讨论】:

      猜你喜欢
      • 2021-09-23
      • 2012-05-29
      • 2016-08-02
      • 1970-01-01
      • 2016-11-14
      • 2018-06-20
      • 2017-02-28
      • 2015-07-25
      相关资源
      最近更新 更多