#c #pointers #iterator
#c #указатели #итератор
Вопрос:
Я изучаю C и столкнулся с аналогичной ситуацией в своем задании. Каждая из моих попыток решить этот случай сопровождалась несколькими вопросами, поэтому я упростил его здесь.
Для этого сценария я буду использовать этот класс:
class Story {
string _title;
//a simple getter
string getTitle(){
return _title;
}
};
Теперь в моей основной функции у меня есть stories
указатель на вектор с указателями на Story
:
vector<Story *> * stories = function();
Моя цель — получить доступ к _title
первому Story
в моем векторе (размер моего вектора всегда будет больше 0).
Для этого я попробовал несколько методов, которые, как я думал, будут работать:
//Attempt 1 (doesn't work)
*(stories)[0]->title();
//I thought `*(stories)[0]` returns the first `Story*`
/** Error message:
* error: ‘class std::vector<Story*>’ has no member named ‘title’
*/
//Attempt 1.5 (equivalent to Attempt 1)
*(stories).at(0)->title();
//Attempt 2 (works)
stories->at(0)->title();
//Aren't `*(stories).at(0)` and `stories->at(0)` the same?
//Since Attempt 1.5 failed, there as to be a difference..
//Attempt 3 (doesn't work)
stories->begin()->title();
//I thought `stories->begin()` returns the first `Story*`
/** Error message:
* error: request for member ‘title’ in
* ‘* stories->std::vector<Story*>::begin().__gnu_cxx::__normal_iterator<Story**, std::vector<Story*> >::operator->()’, which is of pointer type ‘Story*’
* (maybe you meant to use ‘->’ ?)
*/
Я понимаю, почему моя попытка 2 работает, но я не понимаю, почему 1, 1.5 и 3 этого не делают.
На всякий случай я компилирую, используя эти параметры:
--std=c 11 -O0 -ggdb -Wall -Wextra
Комментарии:
1. 🤔 #3 выглядит как опечатка.
2.
*(stories).at(0)
это не то жеstories->at(0)
самое, что .(*stories).at(0)
является. Обратите*
внимание, что находится внутри()
, поэтому значение другое.3. Представьте, если
stories->begin()
бы вы вернули первыйStory*
, как бы вы получили второй? Конечно, он должен возвращать что-то, что вы можете увеличить, чтобы получить следующийStory*
, и это не будет значением первогоStory*
, не так ли?4. Я только что попробовал, как @Peter, для попыток 1 и 1.5. Я никогда не замечал
*
, чтобы add был внутри. На самом деле была опечатка, поскольку @TrebledJ «указал» на попытку 3 и пояснительную справку @DavidSchwat для итератора. Спасибо вам всем.5. C преуспевает в семантике значений. Неважно, как это сделать, пожалуйста, не делайте этого.
vector
может содержать историю напрямую.
Ответ №1:
begin возвращает итератор (указывающий на начало вектора), и итератор должен быть разыменован, чтобы получить элемент, на который он указывает.
С begin()->
помощью (или (*stories->begin())
) вы разыменовываете этот итератор и получаете Story *
, но Story *
не имеет члена title
. Так что это должно быть (*stories->begin())->title()
Или используйте front, поскольку он возвращает ссылку на первый элемент.
Ответ №2:
В случае вашей попытки 3,
stories->begin()
вернет итератор, чтобы напечатать значение, сохраненное в позиции, указанной итератором, попробуйте что-то вроде этого
*(stories->begin())
Комментарии:
1. Действительно, все работает с этим:
(*stories->begin())->title();