Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I was try out some code and am wondering how the const qualifier in C++ applies to pointer types when using 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;
}

I realize there is a similar question asking if they are the same, I am asking more specifically what is the rule here that is getting applied to the deduction of the end pointer type.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
462 views
Welcome To Ask or Share your Answers For Others

1 Answer

In this example, const is being applied to whatever auto deduces, which means both uses result in an object of type int * const, because auto on its own is deducing int *. The ordering that you're imagining takes place based on whether you write it auto const or const auto doesn't happen, in the same way that int const and const int are the same.

An easier way to think about this might be to try the following:

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;

Any variables in this example, whose names only differ due to appended numbers, are equivalent types, as far as C++ is concerned. Note how changing where the const appears doesn't affect the deduced type. This is because the "read-right-to-left" rule for working out how types are declared is based on how raw types are written: once you use constructions like this (or, as you observed, auto) the rules become a lot simpler.

My instinct is that, since your problem sort of implies that you need this kind of fine-grained control over the type system anyways, you should use a using or typedef on pointer<T> like I've showcased here, and use that to declare your types, since it's a lot easier to know, at a glance, what const pointer<int> is than it is to see what int *const is. Especially since it prevents silly mistakes like this:

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 technically solves this problem too, but as you're showing in your example, it's still ambiguous (to you) whether the const is being applied to the pointer itself, or the object it's pointing to, whereas in this case, there's no more ambiguity.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...