繁体   English   中英

如何将BOOST_FOREACH与仅支持const_iterator的容器一起使用?

[英]How can I use BOOST_FOREACH with a container supporting only const_iterator?

我有这个容器:

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类型,这显然会失败。 如何让它实例化常量范围呢?

谢谢。

编辑

以下是RowFieldIterator的完整类声明:

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;
};

一个变通办法 ,如果你真的想避免iterator构件是用一对迭代。

BOOST_FOREACH(Field field, std::make_pair(row.begin(), row.end()))

您的原始代码有什么问题?

一些标准库容器(如std::setstd::multiset )具有全部为const的迭代器(不允许更新)。 该标准具体说:

对于值类型与键类型相同的关联容器,iterator和const_iterator都是常量迭代器。 未指定迭代器和const_iterator是否是同一类型。

你可能会逃脱

typedef const_iterator iterator;

在你的班上

使用boost 1.52(我还没有测试过其他版本), BOOST_FOREACH(Field field, const_cast<Row const&>(row))也可以工作。

FieldIterator似乎与const和非const迭代器方法的迭代器类相同。 BOOST_FOREACH适用于任何包含C风格数组的容器,这使我认为问题出在FieldIterator类中。 你能为它发布代码吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM