13

i have a class that has this function:

typedef boost::shared_ptr<PrimShapeBase> sp_PrimShapeBase; 



class Control{
     public:
         //other functions
         RenderVectors(SDL_Surface*destination, sp_PrimShapeBase);
     private:
         //other vars
          vector<sp_PrimShapeBase> LineVector;

};

//the problem of the program

void Control::RenderVectors(SDL_Surface*destination, sp_PrimShapeBase){
    vector<sp_PrimShapeBase>::iterator i;

    //iterate through the vector
    for(i = LineVector.begin(); i != LineVector.end(); i ++ ){
      //access a certain function of the class PrimShapeBase through the smart
      //pointers
      (i)->RenderShape(destination); 

    }
}

The compiler tells me that the class boost::shared_ptr has no member called 'RenderShape' which I find bizarre since the class PrimShapeBase certainly has that function but is in a different header file. What is the cause of this?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
lambda
  • 1,225
  • 2
  • 14
  • 40
  • Any particular reason you're separating the declaration of the iterator from its initialization? Do you need `i` later? Why not `for (vector::iterator i = LineVector.begin()` or even better `for (auto it = LineVector.begin()`? – fredoverflow Aug 14 '12 at 21:10

2 Answers2

21

Don't you mean

(*i)->RenderShape(destination); 

?

i is the iterator, *i is the shared_ptr, (*i)::operator->() is the object.

Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Weird, he had the parentheses, so it seems like he either mistyped (but then what would cause the problem, not sure)... – user541686 Aug 14 '12 at 21:02
  • ofcourse, how pathetic to let that slip through. derefrencing the iterator. appreciated – lambda Aug 14 '12 at 21:03
  • I can not find any place to explain, why we need to double dereference, instead of using `->` which should IMO recur until it hits true pointer object (or is `shared_ptr` considered to be pointer?). Could you please explain? – sukhmel Oct 01 '14 at 09:31
  • @sukhmel does `std::iterator` have an overloaded `operator->`? – Luchian Grigore Oct 01 '14 at 11:29
  • it does not have an overload, although this operator is defined for iterator, as far as I can understand. Do you mean, that recurring appears only where `->` is overloaded? – sukhmel Oct 01 '14 at 12:41
  • @sukhmel if the iterator has defined `operator->`, that's an overload. If not, how can it be called on that object? – Luchian Grigore Oct 01 '14 at 12:58
7

That's because i is an iterator. Dereferencing it once gives you the smart pointer, you need to double dereference it.

(**i).RenderShape(destination);

or

(*i)->RenderShape(destination); 
Wug
  • 12,956
  • 4
  • 34
  • 54
  • If only *dereference* was a postfix operator, then we could have written `i*->RenderShape(destination);` :) – fredoverflow Aug 14 '12 at 21:02
  • Or some ungodly thing like `i->->RenderShape(destination);` – Wug Aug 14 '12 at 21:03
  • 1
    How about introducing some syntactic sugar like `i-->RenderShape(destination);`? The longer the arrow, the more dereference steps? :) – fredoverflow Aug 14 '12 at 21:04
  • I briefly entertained the thought while authoring my comment, but that would of course be abused in horrible ways. :O – Wug Aug 14 '12 at 21:05
  • @FredOverflow Unless of course it's `i--->RenderShape()`, in which case it would dereference the previous element. – Luchian Grigore Aug 14 '12 at 21:05