2015-02-18 18 views
6

Aşağıdaki kod, p2 const ile bildirilmiş olsa bile, değeri * p2 olarak değiştirmeme izin verir.Bir işaretçi değişkeni ile const ve decltype kullanma

int *p1; 

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

Ancak, ben yerine "* int" "decltype (p1)", daha sonra derleyici bayrakları bir hata kullanırsanız.

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 kullanıyorum.

İşaretçi değişkenine uygulandığında decltype const belirticisini yoksayıyor mu?

cevap

10

, int* const p2 anlamına gelir.

Bu, p2 değiştiremeyeceğiniz anlamına gelir, ancak işaret edilen şeyleri değiştirebilirsiniz.


const T hep T sözde "üst düzey" için const uygular. T, bileşik bir tür (yani, temel tür kümesinden türetilmiş bir tür) olduğunda, const'u daha düşük seviyelere uygulamak istiyorsanız, çemberler boyunca atlamanız gerekir.

T int * olduğunda, üst düzey const eklenmesi int * const verir. * bir seviyeyi sınırlar; *'un altındaki maddelere ulaşmak için *'u manuel olarak kaldırmanız, const'u uygulamanız ve ardından *'u geri yüklemeniz gerekir.

Olası bir çözümdür:

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

@quantdev haklısınız, test yapmadan başka bir SO yanıtından kopyaladım. Başka bir çözüm var mı? –

+0

bildiğim, ilginç bir konu var .. – quantdev

+0

@quantdev 'std :: remove_reference :: type * p2 = ...;' 'dır, ancak bu biraz çirkin olmasına rağmen –

4

std::pointer_traits buraya kullanışlı gelirdi. Bu kod bile p1shared_ptr<int> veya unique_ptr<int> oldu çalışacağına dair

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

Not: std::pointer_traits::element_type ve std::pointer_traits::rebind herhangi işaretçi benzeri türü için iyi çalışacak bir jenerik ifade yazmak için izin verir.