Home > database >  How can I call a method of an object in a list iterator in C ?
How can I call a method of an object in a list iterator in C ?

Time:10-19

I have a list of Point objects in C 11 and I want to combine each point's string value into a longer string. I have a method to get the point as a string in a certain format, but I can't figure out how to call that method while iterating through the list.

This is my code:

  list<Point> points;
  string results = "";
  
  for (int i = 0; i < num_points; i  ) {
    Point ptemp = Point(random01(), random01());
    points.push_back(ptemp);
    results  = ptemp.getStr();
  }
  
  string log_output = "";
  string sep = ",";
  list<Point>::iterator iter;
  for (iter = points.begin(); iter != points.end();   iter) {
    // get the first three points in the log.txt format
    log_output  = *iter.getRawStr(",")   " , ";  
  }

I'm getting this error:

error: ‘std::__cxx11::list<Point>::iterator’ {aka ‘struct std::_List_iterator<Point>’} has no member named ‘getRawStr’
  177 |     log_output  = *iter.getRawStr(",")   " , ";

I've tried taking away the asterisk, using to_string() instead, and reformatting the loop to use an increasing integer i with the iterator methods called separately inside the loop, but it still doesn't work. I've also tried researching it, but I've only seen cout << *iter, not how to specifically call methods from the iterator. What should I do?

CodePudding user response:

It's a case of operator precedence. The . binds more tightly than *, so this

*iter.getRawStr(",")

is actually this

*(iter.getRawStr(","))

That is, it tries to call getRawStr on the iterator (not the thing it's pointing to), and then dereference the result. You want

(*iter).getRawStr(",")

which is equivalent[1] to

iter->getRawStr(",")

[1] Technically, operator -> can be overridden, so a pathological class might define it to do something different than unary *, but no normal, sane C class should do this.

CodePudding user response:

Either write

log_output  = ( *iter ).getRawStr(",")   " , "; 

or

log_output  = iter->getRawStr(",")   " , "; 

Otherwise this expression

*iter.getRawStr(",")

is equivalent to

* ( iter.getRawStr(",") )

CodePudding user response:

The issue here is the . operator having higher precedence than the unary * operator, so the compiler looks for a member getRawStr in std::list::iterator. You need to use () to change this. Alternatively you could use a range-based for loop allowing you to skip the iterator-related code:

for(auto& point : points)
{
    log_output  = point.getRawStr(",")   " , ";
}
  • Related