0

基本上,我正在尝试编写一个包含通用迭代器的基类。

所以显然模板虚函数不起作用,这就是我尝试 boost::any 的原因,但它仍然没有重载 Iterator 的 get() 方法(它不断抛出下面定义的异常)。我似乎也无法将其设为纯虚拟,因为编译器抱怨“虚拟迭代器开始() = 0;” (它说'无法创建抽象类迭代器的实例')。

我有非常具体的限制,我必须/想要遵守,因此可能会考虑问题的替代解决方案,但可能无法使用。

这是代码的一部分:

  template <class T, class C>
  class Iterator
  {
    public:
      virtual T& operator*() { T *t = boost::any_cast<T>(&get()); return *t; };
      virtual boost::any& get() { throw new Exception("get not overridden!!"); };
      //virtual boost::any& get() = 0;
    protected:
      C::iterator iter;
  };

  template <class T>
  class VectorIterator: public Iterator<T, std::vector<T> >
  {
    public:
      VectorIterator(std::vector<T>::iterator iterator): Iterator<T, std::vector<T> >(iterator) { };
      virtual boost::any& get() { return *iter; };
  };

  template <class Value, class Container>
  class Repository
  {
    public:
      typedef Iterator<Value, Container> iterator;

      virtual iterator begin() = 0;
      virtual iterator end() = 0;
  };


  class SomeRepository : public Repository<RandomClass, std::vector<RandomClass> >
  {
    public:
      iterator begin() { return VectorIterator<RandomClass>(items.begin()); };

      iterator end() { return VectorIterator<RandomClass>(items.end()); };
  }

那么,为什么它不起作用以及(如何)我可以修复它?

PS:我知道这与另一个问题非常相似,但我无法将其完全放入评论中,并且真的不知道我还能把它放在哪里。

更新:

所以我设法通过让 get() 返回一个 void (eww) 指针并忘记 boost::any 来解决问题。但它仍然调用 Iterator::get 而不是 VectorIterator::get (这是我最初的问题)(当我尝试使用 *someRepository.begin() 之类的东西时),有人知道为什么吗?

4

2 回答 2

3

您无法初始化boost::any&from *iter,就像您无法float&从 type 的值初始化一样int。在这两种情况下,都没有要引用的所需类型的实际对象。

您可以更改get为 return boost::any(在这种情况下,*iter将发生转换),但是您operator*有一个问题,即T它想要引用的(再次,引用类型)需要比函数调用更有效。一种解决方案是将调用的结果存储在get某处,或者通过同样返回值 () 而不是引用 () 来执行get相同operator*T更改T&。这些将是价值语义,而不是对底层容器的“浅层”视图。分配给 的结果operator*,假设它是正确的,不会影响容器的元素。

另一种可能性是让getreturn aboost::any保证将浅视图存储到元素中,例如

virtual boost::any get() { return &*iter; }

return boost::ref(*iter);是另一种可能)

然后必须注意内部operator*以正确恢复预期值,例如return *boost::any_cast<T*>(get());(resp. return boot::any_cast<boost::reference_wrapper<T> >(get()).get();)。这具有参考语义,返回T&就可以了。对结果的操作operator*可能会影响容器的元素。

于 2012-10-03T16:21:49.810 回答
0

如果你在'iterator begin()'中返回Iterator(所以按值返回),它会将返回值转换为Iterator,因此它将不再是VectorIterator类型,显然它不会调用VectorIterator的get方法(至少我是这样的)思考)。通过引用或指针返回应该可以正常工作。

现在我只需要想出一个解决方法。通过引用返回将不起作用,因为我在 VectorIterator::begin() 中返回了一个局部变量。我想除非其他人有更好的建议,否则我将不得不按指针返回。

于 2012-10-04T08:12:33.900 回答