Reputation: 307
I have a list<Thing*> clothes
. I want to print out things
to a desired format:
+- shirt
+- pants
\\ shoes
So basically the output is the same for all but the last iteration. So far I've attempted this:
string CCloset::OutputContent() const {
string output;
for(auto i : this->clothes) {
if( next(i) == this->clothes.end() ) {
output.append("\\");
} else {
output.append("+-");
}
output.append( i->Output() );
}
return output;
}
The theory is that if next iteration causes iterator i
to be at list.end()
it means we're at the last element so we slightly modify the output. The compiler says Can't compare structures
.
next()
returns iterator pointing to the next element. In the case of last element, it would point to past-the-end of list. list.end()
returns iterator pointing to past-the-end of list.
What am I missing?
Upvotes: 0
Views: 933
Reputation: 48938
i
is not an iterator. std::next
can only be called with a ForwardIterator or an InputIterator, not with an element of a container.
This is one of the only use-cases for iterator based loops:
for(auto it = clothes.begin(); it != clothes.end(); ++it) {
if( it + 1 == clothes.end() ) {
output.append("\\");
} else {
output.append("+-");
}
output.append( (*it)->Output() );
}
Upvotes: 1
Reputation: 27756
As commenters already noted, i
is not an iterator, but the value of the element.
If you modify the loop to use a reference instead of a value, you can compare the address of the current element with the address of the last element like this:
for( const auto& i : this->clothes ) {
if( &i == &this->clothes.back() ) {
output.append("\\");
} else {
output.append("+-");
}
output.append( i->Output() );
}
Upvotes: 3