определение типа и контейнеры указателей константы

Следующая строка кода компилирует очень хорошо и ведет себя:

list<const int *> int_pointers;  // (1)

Следующие две строки не делают:

typedef int * IntPtr;
list<const IntPtr> int_pointers;  // (2)

Я получаю те же самые ошибки компиляции для

list<int * const> int_pointers;  // (3)

Я хорошо знаю, что последняя строка не законна, так как элементы контейнера STL должны быть присваиваемыми. Почему компилятор интерпретирует (2) для совпадения с (3)?

8
задан Dan Hook 27 January 2010 в 16:58
поделиться

5 ответов

Краткий ответ:

  1. - это список указателей для постоянного INT.
  2. - это список постоянных указателей для INTS.
  3. такой же, как 2.

const (и волатильный), следует естественным образом появиться после того, как тип они квалифицируются. Когда вы пишете его ранее, компилятор автоматически переписывает его внутренне:

const int *

становится

int const *

, который является указателем на постоянную int. Списки этого будут компилировать штрафа, поскольку сам указатель все еще присваивается.

9
ответ дан 5 December 2019 в 05:26
поделиться

Вы читаете объявления типа C-стиля влево налево. Так что «Const Int *» является указателем для постоянного INT («Const Int» и «Int Const» означает то же самое). Это совершенно присваимы. Но (2) и (3) являются постоянными указателями для INT и, следовательно, не присвоены.

8
ответ дан 5 December 2019 в 05:26
поделиться

Вы спрашиваете: «Почему интерпретация компилятора (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 , когда вам нужен версия указателя к типа.

6
ответ дан 5 December 2019 в 05:26
поделиться

const Intptr и const int * не то же самое.

1) const int * - «Указатель на const int ».

2) Const Intptr расширяется до int * const (думаю (int *) const ), который является « const INT ».

Короче говоря, Typedef действует как набор скобок. Вы не можете изменить const , что такое Typedef 'D указатель указывает на.

5
ответ дан 5 December 2019 в 05:26
поделиться

Я не думаю, что эта задача может быть достигнута одним регулярным выражением. У меня нет доказательства того, что это так, но есть довольно много вещей, которые не могут быть сделаны с Regexes, и я ожидал, что эта проблема была одним из них. Некоторые хорошие примеры ограничений Regexes приведены в в этом посте в блоге .

-121--2410594-

Вы должны только HTML кодировать при выводе чего-то в браузере. Это предотвращает XSS атаки. Вид сбежав на то, что вы делаете, когда вы собираете данные из формы, прежде чем вставить его в базу данных, - это HTML кодировка. Он убегает специальные символы базы данных (наилучшим образом, используя параметризованные запросы). Целью этому является предотвращение приступов инъекций SQL. Так что нет двойной кодировки.

-121--2685044-

const int * совпадает с записью int const * , что означает постоянное значение, указанное на неотъемлемом указателе.

С помощью Typedef вы определяете саму указатель как постоянную, как в вашем 3-м заявлении.

3
ответ дан 5 December 2019 в 05:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: