Problem with iterator_facade
Hi, I have the following iterator_facade class: class PassIterator : public boost::iterator_facade< PassIterator, Pass, boost::forward_traversal_tag > { public: PassIterator(); PassIterator( Effect const& effect ); private: void increment(); Pass& dereference() const; Pass m_pass; friend class boost::iterator_core_access; }; Note how my Pass object is stored by-value in my PassIterator class. When I attempt to compile this class, it fails because dereference() is const and it is trying to return a reference to a const member. However, if I make dereference() non-const, it still fails because the base class is calling into PassIterator::dereference() through a const member function as well, so dereference() *must* be const in order to be callable by boost. How can I overcome this issue? const_cast? mutable? Thanks.
Robert Dailey wrote:
Hi,
I have the following iterator_facade class:
class PassIterator : public boost::iterator_facade< PassIterator, Pass, boost::forward_traversal_tag > { public: PassIterator();
PassIterator( Effect const& effect );
private: void increment(); Pass& dereference() const;
Pass m_pass;
friend class boost::iterator_core_access; };
Note how my Pass object is stored by-value in my PassIterator class. When I attempt to compile this class, it fails because dereference() is const and it is trying to return a reference to a const member. However, if I make dereference() non-const, it still fails because the base class is calling into PassIterator::dereference() through a const member function as well, so dereference() *must* be const in order to be callable by boost.
How can I overcome this issue? const_cast? mutable? Thanks.
I guess you want: class PassIterator : public boost::iterator_facade< PassIterator, const Pass, // #1 boost::forward_traversal_tag > ... const Pass& dereference() const; // #2 ... }; Alternatively you could do this: class PassIterator : public boost::iterator_facade< PassIterator, Pass, // #1 boost::forward_traversal_tag, Pass // #2 > ... Pass dereference() const; // #3 ... }; Greetings from Bremen, Daniel Krügler
On Wed, Sep 17, 2008 at 6:21 AM, Daniel Krügler
I guess you want:
<snip>
Alternatively you could do this:
<snip>
Well I don't want to return by value, and I most certainly don't want to return a const reference (Since this Pass object must be mutable). For now I did a const_cast in the dereference() function and now I'm returning a non-const reference. If there is no solution to this, then this is broken. Any chance boost can fix this? I really don't think it makes much since for constness to be an issue here when I never designed my iterator to be const to begin with.
Robert Dailey wrote:
On Wed, Sep 17, 2008 at 6:21 AM, Daniel Krügler
wrote: I guess you want:
<snip>
Alternatively you could do this:
<snip>
Well I don't want to return by value, and I most certainly don't want to return a const reference (Since this Pass object must be mutable). For now I did a const_cast in the dereference() function and now I'm returning a non-const reference.
If there is no solution to this, then this is broken. Any chance boost can fix this? I really don't think it makes much since for constness to be an issue here when I never designed my iterator to be const to begin with.
Of-course there exists a solution, but I misunderstood your original request. I think you should declare your member as mutable, which is the safest way here. If you would use const_cast you would land on UB island if someone tries to work with a const PassIterator. - Daniel
On Wed, Sep 17, 2008 at 10:45 AM, Daniel Krügler
Of-course there exists a solution, but I misunderstood your original request. I think you should declare your member as mutable, which is the safest way here. If you would use const_cast you would land on UB island if someone tries to work with a const PassIterator.
Thanks for the help guys. I'll use mutable.
on Tue Sep 16 2008, "Robert Dailey"
Hi,
I have the following iterator_facade class:
class PassIterator : public boost::iterator_facade< PassIterator, Pass, boost::forward_traversal_tag > { public: PassIterator();
PassIterator( Effect const& effect );
private: void increment(); Pass& dereference() const;
Pass m_pass;
friend class boost::iterator_core_access; };
Note how my Pass object is stored by-value in my PassIterator class. When I attempt to compile this class, it fails because dereference() is const and it is trying to return a reference to a const member. However, if I make dereference() non-const, it still fails because the base class is calling into PassIterator::dereference() through a const member function as well, so dereference() *must* be const in order to be callable by boost.
How can I overcome this issue? const_cast? mutable? Thanks.
Mutable, it seems to me. Dereference must be a non-mutating operation on the iterator itself. The fact that the referenced object happens to be stored inside the iterator notwithstanding, it is not logically a part of the iterator's value. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (3)
-
Daniel Krügler
-
David Abrahams
-
Robert Dailey