beginh February 2016

Using iterator over set of pointers to call it's pointer object methods

I am a beginner as comes to working with iterators and want to iterate through names of my points printing them out. I do not know how to access them, help me out please with an idea. My approach looks like this:

 set<Point::Ptr> points = world->getPoints(); // have set of pointers to Point

 Point::CPtr myPoint = *points.begin(); // dereferenced iterator to the first element
 Point::CPtr lastPoint = *points.rbegin(); //dereferenced iterator to the last valid element

 for(set<Point::Ptr>::iterator it = *points.begin(); it != points.end(); it++) {
    ROS_INFO("points are: %s: ", myPoint.get()->getName().c_str());
 }

Normally for iterator in a loop it shall be set to the first element of the set. But since set contains pointers and I want to be able to call functions available for objects inside those pointers, I tried this way. It works for a one only element like that, giving me desired name:

ROS_INFO("myPoint pointer gives %s: ", myPoint.get()->getName().c_str());

EDIT: typedef boost::shared_ptr CPtr;

Answers


R Sahu February 2016

Using

for(set<Point::Ptr>::iterator it = *points.begin(); it != points.end(); it++)

is a problem since it is an iterator, but *points.begin() is not. You need to use:

for(set<Point::Ptr>::iterator it = points.begin(); it != points.end(); it++)
{
   Point::CPtr myPoint = *it;
   // Now you can use myPoint
}

If you are able to use a C++11 compiler, you simplify that with a range-for loop.

for( auto myPoint : points)
{
   // Now you can use myPoint
}


iksemyonov February 2016

it in the loop below is an iterator. Hence, to access the element that it refers to, you need to dereference it (*it)or use the member access operator (it->).

set<Point::Ptr> points = world->getPoints(); // have set of pointers to Point

for(set<Point::Ptr>::iterator it = points.begin(); it != points.end(); it++) {
   ROS_INFO("points are: %s: ", it->get()->getName().c_str());
   ROS_INFO("points are: %s: ", (*it).get()->getName().c_str());
}

There also is a typo or a deliberate syntax error here:

for(set<Point::Ptr>::iterator it = *points.begin(); it != points.end(); it++) {
//                                ^^^

You want the iterator itself to iterate over the loop, not the value it refers to.

Edit: for OP's and future reference moved here from a comment:

I don't have a reference to Point::Ptr, but it appears to be a pointer class. Thus, to get the Point object that an object of this pointer class stores, you need to call get(). This function returns you a Point* pointer (which is also called a raw pointer) that you can then use like you always use pointers to class objects. In short, this is an example of the common concept of wrapping raw pointers into (more or less) smart pointer classes.

See:

for(set<Point::Ptr>::iterator it = points.begin(); it != points.end(); it++) {
   const Point::Ptr pointer= *it;
   ROS_INFO("points are: %s: ", pointer.get()->getName().c_str());
}

One more edit:

Normally for iterator in a loop it shall be set to the first element of the set.

Wrong. The iterator is set to the iterator pointing to the first element of the set. As @RSahu also pointed out below, you can't assign a containe

Post Status

Asked in February 2016
Viewed 1,593 times
Voted 8
Answered 2 times

Search




Leave an answer