以下代码允许我更改* p2处的值,即使p2是用const。
声明的int *p1;
const decltype(p1) p2 = new int(100);
*p2 = 200;
cout << "*p2: " << *p2 << endl; // Outputs *p2: 200
但是,如果我使用&#34; int *&#34;而不是&#34; decltype(p1)&#34;,然后编译器标记错误。
const int * p2 = new int(100);
*p2 = 200;
cout << "*p2: " << *p2 << endl;
error: assignment of read-only location ‘* p2’
*p2 = 200;
^
我正在使用g ++(Ubuntu 4.8.2-19ubuntu1)4.8.2。
当应用于指针变量时,decltype是否忽略const说明符?
答案 0 :(得分:10)
const decltype(p1) p2
表示int* const p2
。
这意味着您无法更改p2
,但您可以更改指向的内容。
const T
始终将const应用于所谓的&#34;顶级&#34; T
。当T
是复合类型(即,从基本类型集构建的类型)时,如果要将const
应用于较低级别,则必须跳过箍。
当T为int *
时,添加顶级const将给出int * const
。 *
划定了一个级别;要获得*
以下的内容,您必须手动删除*
,应用const
,然后再放回*
。
可能的解决方案是:
const std::remove_pointer<decltype(p1)>::type *p2 = new int(100);
答案 1 :(得分:4)
std::pointer_traits
会派上用场。 std::pointer_traits::element_type
和std::pointer_traits::rebind
允许您编写一个通用表达式,它适用于任何类似指针的类型:
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);
请注意,即使p1
为shared_ptr<int>
或unique_ptr<int>
,此代码也会有效。