Почему использование указателя позволяет мне использовать оператор скобок в std :: list? - PullRequest
0 голосов
/ 22 октября 2019

Я немного изучал хеш-таблицы и как их создавать с помощью цепочек в C ++. В примере кода, который я нашел, список и сегменты объявляются следующим образом:

int bucket;
std::list<int> *table;

Затем в других местах программы что-то подобное называется:

table[bucket].push_back(1);

Мой вопросПочему, объявляя * table, я могу использовать оператор скобки [], но если я объявляю его без *, тогда я больше не могу использовать оператор скобки?

ex:

std::list<int> *table;
table[bucket].... OKAY

std::list<int> table;
table[bucket]... NOT OKAY

Так что когда * используется, этокак будто есть список в каждом ведре. поэтому таблица [1] - это список, таблица [2] - это другой список. Как они достигают этого с помощью *?

Я заметил, что я могу сделать это и с другими типами

ex:
int *test;
test[index]... OKAY

int test;
test[index]... NOT OKAY

это, очевидно, связано с объявлением указателя, но после бесчисленного количествачитая и оглядываясь вокруг, я не могу этого понять. Я думаю, что "std :: list * table" создает указатель на список. Но это ничего не говорит о том, как я теперь могу использовать [].

Любое разъяснение очень ценится.

Ответы [ 2 ]

2 голосов
/ 22 октября 2019

«Арифметика указателя» - это ключевая концепция, которую нужно понять.

Для std::list<int> table (†), table[1] эквивалентно *(table + 1). Концептуально это означает: «посмотрите на адрес памяти, на который указывает таблица. Посмотрите на один sizeof(table) справа и дайте мне std::list<int>, который там есть.

(†) Или любой другой тип по этому вопросу. , но я придерживался std::list<int> для согласованности с вашим вопросом.

Так, например, если у нас есть следующее:

const char* foo = "Hi!";

, то следующие значения эквивалентны:

foo[2];
*(foo + 2);
*(2 + foo);
2[foo];
1 голос
/ 22 октября 2019

Указатель может использовать оператор [], как если бы он был массивом. Вот почему это компилируется. Однако ваш указатель неинициализирован, поэтому доступ к чему-либо с ним - неопределенное поведение. Вот почему выглядит как для работы с указателем.

Класс std::list не поддерживает произвольный доступ и, следовательно, не поддерживает оператор []. Вот почему он не компилируется, если вы не определите его как указатель.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...