我有这个容器:
class /*final*/ Row
{
public:
typedef FieldIterator const_iterator;
typedef FieldIterator iterator;
FieldIterator begin() const;
FieldIterator end() const;
FieldIterator begin();
FieldIterator end();
...
};
鉴于此,以下代码编译得很好:
BOOST_FOREACH(Field field, row)
{
}
但是,Row
类不应该有可变迭代器,所以我通过删除可变访问来改变了Row类:
class /*final*/ Row
{
public:
typedef FieldIterator const_iterator;
FieldIterator begin() const;
FieldIterator end() const;
...
};
但现在同样的foreach循环无法编译:
1>o:\c\boost_1_48_0\boost\foreach.hpp(364): error C2039: 'type' : is not a member of 'boost::mpl::eval_if<C,F1,F2>'
1> with
1> [
1> C=boost::mpl::false_,
1> F1=boost::range_const_iterator<sqlserver::Row>,
1> F2=boost::range_mutable_iterator<sqlserver::Row>
1> ]
1> c:\dev\internal\playmssqlce\playmssqlce.cpp(29) : see reference to class template instantiation 'boost::foreach_detail_::foreach_iterator<T,C>' being compiled
1> with
1> [
1> T=sqlserver::Row,
1> C=boost::mpl::false_
1> ]
...
从错误消息我明白BOOST_FOREACH
尝试实例化range_mutable_iterator
类型,这显然会失败。如何让它实例化常量范围?
感谢。
修改
以下是Row
和FieldIterator
的完整类声明:
class /*final*/ Row
{
const BYTE *m_buffer;
const DBBINDING *m_pColumnBindings;
int m_columnBindingCount;
FieldIterator m_end;
public:
typedef FieldIterator const_iterator;
typedef FieldIterator iterator;
Row(const BYTE *buffer, const DBBINDING *pColumnBindings, int columnBindingCount);
bool isSameRow(const Row& r) const;
int fieldCount() const;
Field field(int i) const;
Field& field(int i, void *fieldBuffer) const;
FieldIterator begin() const;
FieldIterator end() const;
FieldIterator begin();
FieldIterator end();
};
class FieldIterator : public iterator_facade<FieldIterator, Field, boost::random_access_traversal_tag>
{
const Row *m_pRow;
int m_index;
mutable BYTE m_fieldBuffer[sizeof(Field)];
public:
FieldIterator(const Row *pRow = NULL, int index = 0);
private:
friend class boost::iterator_core_access;
void increment();
void decrement();
void advance(difference_type n);
difference_type distance_to(FieldIterator it);
reference dereference() const;
bool equal(const FieldIterator& rhs) const;
};
答案 0 :(得分:6)
解决方法如果你真的想避免iterator
成员,那就是使用一对迭代器。
BOOST_FOREACH(Field field, std::make_pair(row.begin(), row.end()))
答案 1 :(得分:5)
原始代码有什么问题?
某些标准库容器(如std::set
和std::multiset
)具有全部为const的迭代器(不允许更新)。该标准具体说:
对于关联容器,其中 值类型与键类型相同,iterator和const_iterator都是常量迭代器。它是 未指定iterator和const_iterator是否是同一类型。
你可能会逃脱
typedef const_iterator iterator;
在你班上。
答案 2 :(得分:0)
FieldIterator
似乎与const和非const迭代器方法的迭代器类相同。 BOOST_FOREACH
适用于任何包含C风格数组的容器,这使我认为问题出在FieldIterator
类中。你可以为它发布代码吗?
答案 3 :(得分:0)
使用boost 1.52(我没有使用其他版本进行测试),BOOST_FOREACH(Field field, const_cast<Row const&>(row))
也可以使用。