Using const and decltype with a pointer variable

The following code allows me to change the value to * p2, although p2 is declared with a constant.

int *p1; const decltype(p1) p2 = new int(100); *p2 = 200; cout << "*p2: " << *p2 << endl; // Outputs *p2: 200 

However, if I use "int *" instead of "decltype (p1)", then the compiler puts an error.

 const int * p2 = new int(100); *p2 = 200; cout << "*p2: " << *p2 << endl; error: assignment of read-only location '* p2' *p2 = 200; ^ 

I am using g ++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2.

Does decltype tell you to ignore the const specifier when you apply a pointer to a variable?

+6
source share
2 answers

const decltype(p1) p2 means int* const p2 .

This means that you cannot change p2 , but you can change what it points to.


const T always applies const to the so-called "upper level" T When T is a composite type (that is, a type created from a basic set of types), you will have to jump over the hoops if you want to apply const to the lower levels.

When T is int * , adding a top level const will give int * const . * marks the level; to get the information below * , you need to manually remove * , apply const , and then return * .

Possible Solution:

 const std::remove_pointer<decltype(p1)>::type *p2 = new int(100); 
+10
source

std::pointer_traits in handy here. std::pointer_traits::element_type and std::pointer_traits::rebind allow you to write a general expression that will work well for any type of pointer:

 using element_type = std::pointer_traits<decltype(p1)>::element_type; using pointer_like_to_const = std::pointer_traits<decltype(p1)>::rebind<std::add_const_t<element_type>>; pointer_like_to_const p2 = new int(100); 

Note that this code would work even if p1 was shared_ptr<int> or unique_ptr<int> .

+4
source

Source: https://habr.com/ru/post/982658/


All Articles