
Hi, I've been trying to get indirect_iterator working in what seems (to me) to be a straightforward context -- I have a std::vector of boost::shared_ptr objects, and I need both const and non-const iterators into the vector (I'm using the vector as the sole data member of a container class, and I need the iterators to properly handle const and non-const container types). This looks something like this: class MyClass { // ... }; class MyContainer { public: typedef MyClass value_type; typedef value_type & reference; typedef value_type * pointer; // and so on, for const_reference, const_pointer, etc... // ... private: std::vector<boost::shared_ptr<MyClass> > _data; }; Now, the trouble comes when I attempt to define the iterators for MyContainer using the indirect_iterator generators. If I do the obvious: Approach #1: ------------ typedef indirect_iterator_pair_generator< vector<shared_ptr<MyClass> >::iterator, value_type, reference, const_reference, std::random_access_iterator_tag, pointer, const_pointer>::itgen; typedef typename itgen::iterator my_iterator; typedef typename itgen::const_iterator my_const_iterator; I find that the const_iterator generated is inadequate for use in a container context. Particularly, it produces a my_const_iterator that has the following constructor signature: my_const_iterator(shared_ptr<MyClass> *) Whereas, a const std::vector<shared_ptr<MyClass> > will produce const_iterators that look like this: const shared_ptr<MyClass> * const This causes compilation problems, because inevitably, in this context, you'll want to construct a my_const_iterator from a vector::const_iterator. The problem seems obvious: the indirect_iterator_pair_generator class is considering only non-const base iterators. This led me to try the following: Approach #2: ----------- typedef typename indirect_iterator_generator <typename vector<shared_ptr<MyClass> >::iterator, value_type, reference, pointer, std::random_access_iterator_tag>::type my_iterator; typedef typename indirect_iterator_generator <typename vector<shared_ptr<MyClass> >::const_iterator, value_type, const_reference, const_pointer, std::random_access_iterator_tag>::type my_const_iterator; It seemed that this would solve the problem by independently generating the two types of iterators that are needed (note how I've made the base iterator type ::iterator in one, and ::const_iterator in the other). However, with this method I always obtain compilation errors -- whereever there is a use of the operator->(), the following error is produced (g++ 3.0.3 and 3.2 do the same thing, Linux and Mac OSX): "result of `operator->()' yields non-pointer result" I have yet to figure out what is causing this error. This led me to attempt the following "solution" to the problem: Approach #3: ----------- typedef indirect_iterator_pair_generator <typename vector<shared_ptr<MyClass> >::iterator, value_type,reference,const_reference, std::random_access_iterator_tag, pointer,const_pointer> itgen; typedef typename itgen::iterator my_iterator; typedef indirect_iterator_pair_generator <typename vector<shared_ptr<MyClass> >::const_iterator, value_type,reference,const_reference, std::random_access_iterator_tag, pointer,const_pointer> itgen2; typedef typename itgen2::const_iterator my_const_iterator; This actually works! I can't explain why -- it seems like indirect_iterator_pair_generator and indirect_iterator_generator should behave identically when their template parameters are identical.... The way I see it, there's a bug in at least one of the indirect_iterator generator objects. At the very least, indirect_iterator_pair_generator and indirect_iterator_generator are behaving differently when their parameter types are the same (compare approaches #2 and #3). But there's also the issue of why approach #1 didn't work to begin with -- it *seems* like indirect_iterator_pair_generator should produce a const_iterator type that can be initialized with an iterator from a const vector. This isn't the case. If anyone can explain this to me, and convince me that I'm not going insane, I'd appreciate it greatly ;-) (Standard bug-report disclaimers: Current boost distribution, g++ 3.0.x/3.2.x, both Mac OSX and Linux exhibit identical behaviour.) -Tim