2016-01-20 3 views
1

const PointerToNonConst& value Почему понимается как A* const для кода ниже:Почему const Ссылка на не-const указатель интерпретируется как указатель const?

using PointerToNonConst = A*; // or typedef A* PointerToNonConst; 
const PointerToNonConst& value; // compiled and understood as `A* const` 

Я ожидал, что он будет доступен только для чтения указатель вместо этого на постоянной указателю.

КСТАТИ здесь является использование регистра, поэтому вы можете встретить это в вашем коде:

class A 
{ 
public: 
    void callOnNonConstMethodIsValid() 
    { 
     // change the object here 
    } 
} 

std::vector<A*> vect; 

for (const auto& elem : vect) 
{ 
    elem->callOnNonConstMethodIsValid(); // no error 
} 
+1

Несомненно, это 'A * const &' ... – ildjarn

ответ

3

typedef и using не такие как #define. Это не замена текста. Когда вы создаете псевдоним типа с typedef или using, это имя обрабатывается как единое целое. Когда вы применяете к нему const, он применяет тип в целом на верхнем уровне. Вы не можете применить его к внутренним компонентам этого типа.

+0

Делает полный смысл, но в этом случае я читаю 'const NonConstPtr & value' как ссылку только на чтение для указателя не для чтения. Так что, наконец, это только для чтения или нет? Это сбивает с толку. Каков правильный способ его прочитать? – Narek

+0

@Narek: Если вы понимаете, что запись 'const' до того, как тип на самом деле является особым случаем в грамматике, и вы должны написать его после типа, то вы можете читать типы C и C++ справа налево. Поэтому я бы написал это как «NonConstPtr const & value» и прочитал его как * «значение - ссылка на const NonConstPtr» *. Но это имя довольно запутанно. Причина в том, что это запутанно, но из-за имени, которое вы дали типу: '' NonConstPtr''. Более точное имя будет «PointerToNonConst» ' –

+0

И тогда декларация будет выглядеть так:' PointerToNonConst const & value' и может быть прочитана как * "значение является ссылкой на const PointerToNonConst" *. –

2

Учитывая

using NonConstPtr = A*; // or typedef A* NonConstPtr; 

Декларации

const NonConstPtr& value = <initializer>; 

эквивалентно

A* const& value = <initializer>; 

value является ссылкой на указатель const на объект типа A.

Это не эквивалентно:

const A*& value = <initializer>; 

где value является ссылкой на указатель на const A.

Это один из случаев, когда имеет смысл использовать ключевое слово const после типа.

NonConstPtr const& value = <initializer>; 

Если вы это сделаете, может возникнуть больше смысла, почему первая интерпретация верна.

+0

Он * всегда * имеет смысл поставить 'const' после типа. Тот факт, что вы даже можете сказать это раньше, - это особый случай в грамматике. –

+0

@ BenjaminLindley, я согласен. Я предпочитаю ставить 'const' после типа. –

+0

@RSahu Я бы принял ваш ответ, если бы был способ. – Narek

Смежные вопросы