Следующая строка кода компилирует очень хорошо и ведет себя:
list<const int *> int_pointers; // (1)
Следующие две строки не делают:
typedef int * IntPtr;
list<const IntPtr> int_pointers; // (2)
Я получаю те же самые ошибки компиляции для
list<int * const> int_pointers; // (3)
Я хорошо знаю, что последняя строка не законна, так как элементы контейнера STL должны быть присваиваемыми. Почему компилятор интерпретирует (2) для совпадения с (3)?
Краткий ответ:
const (и волатильный), следует естественным образом появиться после того, как тип они квалифицируются. Когда вы пишете его ранее, компилятор автоматически переписывает его внутренне:
const int *
становится
int const *
, который является указателем на постоянную int. Списки этого будут компилировать штрафа, поскольку сам указатель все еще присваивается.
Вы читаете объявления типа C-стиля влево налево. Так что «Const Int *» является указателем для постоянного INT («Const Int» и «Int Const» означает то же самое). Это совершенно присваимы. Но (2) и (3) являются постоянными указателями для INT и, следовательно, не присвоены.
Вы спрашиваете: «Почему интерпретация компилятора (2) будет таким же, как (3)?». Ну, потому что на языке C ++ (а также в C) они являются семантически одинаковыми. Когда вы определяете типовое значение как
typedef int *IntPtr;
, то позже тип Const Intptr
будет стоять для int * const
, не для const int *
. Это как раз, как Typedef-имена работают в C ++.
Typedef-names в C ++ не Macros. Хотя они не определяют новые типы (просто псевдонимы для существующих), полученные псевдонимы, тем не менее, «атомные», «монолитные» в том смысле, что любые квалификаторы, применяемые к псевдонису, будут применяться как верхний уровень Квалификаторы. Когда вы работаете с TypeDef-name, нет никакого способа «подкрадывать», что «Const Qualifier так, чтобы это было бы как-то» сходить »на более низкую часть типа типа ( INT
в вашем случае) Отказ
Если вы настаиваете на использовании Typedef-names, у вас нет другого немедленного выбора, кроме как предоставлять два разных типа Typedef, таких как
typedef int *IntPtr;
typedef const int *ConstIntPtr;
и использование ConstIntptr
, когда вам нужен версия указателя к типа.
const Intptr
и const int *
не то же самое.
1) const int *
- «Указатель на const int
».
2) Const Intptr
расширяется до int * const
(думаю (int *) const
), который является « const
INT
».
Короче говоря, Typedef
действует как набор скобок. Вы не можете изменить const
, что такое Typedef
'D указатель указывает на.
Я не думаю, что эта задача может быть достигнута одним регулярным выражением. У меня нет доказательства того, что это так, но есть довольно много вещей, которые не могут быть сделаны с Regexes, и я ожидал, что эта проблема была одним из них. Некоторые хорошие примеры ограничений Regexes приведены в в этом посте в блоге .
-121--2410594-Вы должны только HTML кодировать при выводе чего-то в браузере. Это предотвращает XSS атаки. Вид сбежав на то, что вы делаете, когда вы собираете данные из формы, прежде чем вставить его в базу данных, - это HTML кодировка. Он убегает специальные символы базы данных (наилучшим образом, используя параметризованные запросы). Целью этому является предотвращение приступов инъекций SQL. Так что нет двойной кодировки.
-121--2685044- const int *
совпадает с записью int const *
, что означает постоянное значение, указанное на неотъемлемом указателе.
С помощью Typedef вы определяете саму указатель как постоянную, как в вашем 3-м заявлении.