Вы спрашиваете «Почему компилятор интерпретирует (2) так же, как (3)?». Ну, потому что в языке C ++ (как и в C) они семантически . Когда вы определяете имя типа как
typedef int *IntPtr;
, затем тип const IntPtr
будет означать int *const
, а не const int *
. Именно так работают имена типов в C ++.
Имена типов в C ++ не являются макросами. Хотя они не определяют новые типы (только псевдонимы для существующих), полученные псевдонимы, тем не менее, являются «атомарными», «монолитными» в том смысле, что любые квалификаторы, примененные к псевдониму, будут применяться как верхнего уровня классификаторы. Когда вы работаете с typedef-name, нет никакого способа «проникнуть» в спецификатор const, чтобы он каким-то образом «опустился» до части типа более низкого уровня (int
в вашем случае).
Если вы настаиваете на использовании typedef-имён, у вас нет другого немедленного выбора, кроме как предоставить два разных typedef-имени, как
typedef int *IntPtr;
typedef const int *ConstIntPtr;
и используйте ConstIntPtr
, когда вам нужна версия типа указатель на констант.