Reputation: 1312
I'm trying to iterate through a Players hand of cards.
#include <vector>
#include <iostream>
class Card {
int card_colour, card_type;
public:
std::string display_card();
};
std::string Card::display_card(){
std::stringstream s_card_details;
s_card_details << "Colour: " << card_colour << "\n";
s_card_details << "Type: " << card_type << "\n";
return s_card_details.str();
}
int main()
{
std::vector<Card*>current_cards;
vector<Card*>::iterator iter;
for(iter = current_cards.begin(); iter != current_cards.end(); iter++)
{
std::cout << iter->display_card() << std::endl;
}
}
This line
std::cout << iter->display_card() << std::endl;
currently comes up with the
error: Expression must have pointer-to-class type.
How can I fix this?
Upvotes: 24
Views: 49700
Reputation: 7625
De-referencing the iterator by iter->
gives a pointer to an object of type Card
, you have to write (*iter)->display_card();
Upvotes: 2
Reputation: 1628
You have to dereference the iterator to access the pointer:
#include <vector>
#include <iostream>
class Card {
public:
std::string display_card();
};
int main() {
std::vector<Card*>current_cards;
std::vector<Card*>::iterator iter, end;
for(iter = current_cards.begin(), end = current_cards.end() ; iter != end; ++iter) {
std::cout << (*iter)->display_card() << std::endl;
}
}
Another observation is the iter++
which you should avoid in profit of ++iter
(see https://stackoverflow.com/a/24904/2077394).
Depending on the container, you may also want to avoid calling end()
each iteration.
Upvotes: 5
Reputation: 5565
An alternative to using (*iter)->
is to pre-emptively dereference the iterator with range-based for.
std::vector<Card*> current_cards;
// Code that populates current_cards goes here...
for(auto p_card : current_cards)
{
std::cout << p_card->display_card() << std::endl;
}
In the above code, p_card
is already a Card*
pointer instead of a std::vector<Card*>::iterator
iterator. To me this is clearer than the version that explicitly dereferences the iterator and then dereferences the pointer, and is certainly more concise. It also means I don't have to worry about operator precedence pitfalls with ->
and unary *
.
Upvotes: 1
Reputation: 54592
Try this:
cout << (*iter)->display_card() << endl;
The *
operator gives you the item referenced by the iterator, which in your case is a pointer. Then you use the ->
to dereference that pointer.
Upvotes: 41