S
Stone Free
Hi,
I've been following the boost Iterator Facade tutorial but cannot seem
to adapt it fully to my needs.
I have a class with which I want to provide an iterator for access,
the iterators concerned will actually use a std::iterator provided by
the vector class, but I want to return my own iterator class that
provides a proxy object instead of the underlying storage of the
vector.
To do this I used boost::iterator_facade to derive a new class, which
would provide the iterator functions by delegating to
vector::iterator, and so the new iterator object holds an instance of
vector::iterator.
I'm mostly finished, but I cannot seem to get the const versions of my
new begin() and end() functions to work. I can successfully get a
const_iterator from and iterator outside the class but not inside the
implementation of begin() and end()
// A CCheckBox class exists, its declararation and implementation are
not relevant to the problem
namespace checkboxes
{
struct SCheckBox
{
UINT nID;
CCheckbox* pButton;
BOOL operator==(const SCheckBox& rhs) const
{
return nID == rhs.nID;
}
};
typedef std::vector<SCheckBox> VEC_CHECKBOX;
};
class SCheckBoxDerefence
{
public:
SCheckBoxDerefence(CCheckbox *pBox) : m_checkbox(pBox){}
//rest of interface not finalised
private:
CCheckbox* m_checkbox;
};
template <class Value>
class checkbox_iter
: public boost::iterator_facade<checkbox_iter<Value>, Value ,
boost::forward_traversal_tag>
{
public:
checkbox_iter() : m_it(checkboxes::VEC_CHECKBOX::iterator()), m_pBox
(NULL) {}
template <class OtherValue>
checkbox_iter(checkbox_iter<OtherValue> const& other)
: m_it(other.m_it) {}
template <class OtherValue>
checkbox_iter& operator=(const checkbox_iter<OtherValue>& other)
{
m_it = other.m_it;
return *this;
}
checkbox_iter(checkboxes::VEC_CHECKBOX::iterator it) : m_it(it),
m_pBox(NULL) {}
//Next line is part of a failed attempt at solving the problem
// checkbox_iter(checkboxes::VEC_CHECKBOX::const_iterator it) : m_it
(it), m_pBox(NULL) {} //compile error 1
private:
mutable boost::scoped_ptr<SCheckBoxDerefence> m_pBox;
friend class boost::iterator_core_access;
template <class> friend class checkbox_iter;
checkboxes::VEC_CHECKBOX::iterator m_it;
void increment() { ++m_it; }
void decrement() { --m_it; }
bool equal(checkbox_iter const& other) const
{
return this->m_it == other.m_it;
}
Value& dereference() const
{
m_pBox.reset(new SCheckBoxDerefence(m_it->pButton));
return *m_pBox;
}
};
class CCheckboxGroup
{
public:
CCheckboxGroup(...) //Unimportant
typedef checkbox_iter<SCheckBoxDerefence> iterator;
typedef checkbox_iter<SCheckBoxDerefence const> const_iterator;
//Following two items work
iterator begin() { return iterator(m_vecCheckboxes.begin()); }
iterator end() { return iterator(m_vecCheckboxes.end()); }
...
};
void Test()
{
CCheckboxGroup::iterator it = pGroup->begin();
CCheckboxGroup::const_iterator cit(it);//Successful
cit = it;//Successful
for (CCheckboxGroup::iterator it = pGroup->begin(); it != pGroup->end
(); ++it)
{
*it;//Successful
}
}
//Error1: error C2664: 'std::vector<_Ty>::iterator::iterator
(std::vector<_Ty>::iterator:ointer)' : cannot convert parameter 1
from 'std::vector<_Ty>::const_iterator' to
'std::vector<_Ty>::iterator:ointer'
with
[
_Ty=checkboxes::SCheckBox
]
and
[
_Ty=checkboxes::SCheckBox
]
and
[
_Ty=checkboxes::SCheckBox
]
No user-defined-conversion operator available that can perform
this conversion, or the operator cannot be called
CheckboxGroup.h(74) : while compiling class-template member
function 'checkbox_iter<Value>::checkbox_iter
(std::vector<_Ty>::const_iterator)'
with
[
Value=const SCheckBoxDerefence,
_Ty=checkboxes::SCheckBox
]
CheckboxGroup.h(117) : see reference to class template
instantiation 'checkbox_iter<Value>' being compiled
with
[
Value=const SCheckBoxDerefence
]
I've been following the boost Iterator Facade tutorial but cannot seem
to adapt it fully to my needs.
I have a class with which I want to provide an iterator for access,
the iterators concerned will actually use a std::iterator provided by
the vector class, but I want to return my own iterator class that
provides a proxy object instead of the underlying storage of the
vector.
To do this I used boost::iterator_facade to derive a new class, which
would provide the iterator functions by delegating to
vector::iterator, and so the new iterator object holds an instance of
vector::iterator.
I'm mostly finished, but I cannot seem to get the const versions of my
new begin() and end() functions to work. I can successfully get a
const_iterator from and iterator outside the class but not inside the
implementation of begin() and end()
// A CCheckBox class exists, its declararation and implementation are
not relevant to the problem
namespace checkboxes
{
struct SCheckBox
{
UINT nID;
CCheckbox* pButton;
BOOL operator==(const SCheckBox& rhs) const
{
return nID == rhs.nID;
}
};
typedef std::vector<SCheckBox> VEC_CHECKBOX;
};
class SCheckBoxDerefence
{
public:
SCheckBoxDerefence(CCheckbox *pBox) : m_checkbox(pBox){}
//rest of interface not finalised
private:
CCheckbox* m_checkbox;
};
template <class Value>
class checkbox_iter
: public boost::iterator_facade<checkbox_iter<Value>, Value ,
boost::forward_traversal_tag>
{
public:
checkbox_iter() : m_it(checkboxes::VEC_CHECKBOX::iterator()), m_pBox
(NULL) {}
template <class OtherValue>
checkbox_iter(checkbox_iter<OtherValue> const& other)
: m_it(other.m_it) {}
template <class OtherValue>
checkbox_iter& operator=(const checkbox_iter<OtherValue>& other)
{
m_it = other.m_it;
return *this;
}
checkbox_iter(checkboxes::VEC_CHECKBOX::iterator it) : m_it(it),
m_pBox(NULL) {}
//Next line is part of a failed attempt at solving the problem
// checkbox_iter(checkboxes::VEC_CHECKBOX::const_iterator it) : m_it
(it), m_pBox(NULL) {} //compile error 1
private:
mutable boost::scoped_ptr<SCheckBoxDerefence> m_pBox;
friend class boost::iterator_core_access;
template <class> friend class checkbox_iter;
checkboxes::VEC_CHECKBOX::iterator m_it;
void increment() { ++m_it; }
void decrement() { --m_it; }
bool equal(checkbox_iter const& other) const
{
return this->m_it == other.m_it;
}
Value& dereference() const
{
m_pBox.reset(new SCheckBoxDerefence(m_it->pButton));
return *m_pBox;
}
};
class CCheckboxGroup
{
public:
CCheckboxGroup(...) //Unimportant
typedef checkbox_iter<SCheckBoxDerefence> iterator;
typedef checkbox_iter<SCheckBoxDerefence const> const_iterator;
//Following two items work
iterator begin() { return iterator(m_vecCheckboxes.begin()); }
iterator end() { return iterator(m_vecCheckboxes.end()); }
...
};
void Test()
{
CCheckboxGroup::iterator it = pGroup->begin();
CCheckboxGroup::const_iterator cit(it);//Successful
cit = it;//Successful
for (CCheckboxGroup::iterator it = pGroup->begin(); it != pGroup->end
(); ++it)
{
*it;//Successful
}
}
//Error1: error C2664: 'std::vector<_Ty>::iterator::iterator
(std::vector<_Ty>::iterator:ointer)' : cannot convert parameter 1
from 'std::vector<_Ty>::const_iterator' to
'std::vector<_Ty>::iterator:ointer'
with
[
_Ty=checkboxes::SCheckBox
]
and
[
_Ty=checkboxes::SCheckBox
]
and
[
_Ty=checkboxes::SCheckBox
]
No user-defined-conversion operator available that can perform
this conversion, or the operator cannot be called
CheckboxGroup.h(74) : while compiling class-template member
function 'checkbox_iter<Value>::checkbox_iter
(std::vector<_Ty>::const_iterator)'
with
[
Value=const SCheckBoxDerefence,
_Ty=checkboxes::SCheckBox
]
CheckboxGroup.h(117) : see reference to class template
instantiation 'checkbox_iter<Value>' being compiled
with
[
Value=const SCheckBoxDerefence
]