常量与可变迭代器:相同的算法不同的代码

时间:2014-11-09 22:50:39

标签: c++ iteration const mutable visitor

我的问题涉及如何重用代码,对于算法,const不知道(可以与常量或可变对象一起使用)?

我们以std::vector迭代器为例 有两个迭代器类共享类似的方法:std::vector::iteratorstd::vector::const_iterator

两个迭代器都指向向量中或向量外的插槽(例如std::vector::end())。
他们都有增量和减量方法。 主要区别在于const_iterator不能用于写入向量。

如果我正在为迭代器编写代码,我怎么能拥有不依赖于访问操作常量的iteratorconst_iterator共享方法?

在我目前的代码中,由于可访问性的不同,我正在复制for_eachvisit方法的代码。 for_each循环是相同的for循环,区别在于应用const_visitor而另一个应用mutable_visitor。

struct Object;

struct Const_Visitor
{
  // Visit function cannot modified the given object.
  virtual void visit(const Object& o) = 0;
};

struct Mutable_Visitor
{
  // The visit function may modify the given object;
  virtual void visit(Object& o) = 0;
};

struct Container
{
  const unsigned int LIMIT = 16;
  Object obj_container[LIMIT];

  // Apply the read-only (constant) visitor
  // to each object in the container
  void for_each(Const_Visitor& cv) const
  {
    // Note:  this loop management is the same
    // as the loop management for the mutable for_each() method.
    for (unsigned int i = 0; i < LIMIT; ++i)
    {
      cv.visit(obj_container[i]);
    }
  }


  // Apply the read/write (mutable) visitor
  // to each object in the container.
  void for_each(Mutable_Visitor& mv)
  {
    // Note:  this loop management is the same
    // as the loop management for the const for_each() method.
    for (unsigned int i = 0; i < LIMIT; ++i)
    {
      mv.visit(obj_container[i]);
    }
  }
};  

在上面的示例中,两个for_each函数的机制相同。只有访客更改。数组中的相同插槽将传递给visit函数。

使用一个带有两个visit方法的访问者可以稍微改变一下,但基本问题仍然存在。

struct Object;

struct Single_Visitor
{
  // Method can't modify the object.
  virtual void visit(const Object& o) = 0;

  // Method may modify the object.
  virtual void visit(Object& o) = 0;
};

struct Container
{
  const unsigned int LIMIT = 16;
  Object obj_container[LIMIT];

  // Apply a visitor to each item in container.
  void for_each(Single_Visitor& sv) const
  {
    for (unsigned int i; i < LIMIT; ++i)
    {
      // Should call the visit method,
      // constant object.
      sv.visit(obj_container[i]);
    }
  }


  // Apply a visitor to each item in container.
  void for_each(Single_Visitor& sv)
  {
    for (unsigned int i; i < LIMIT; ++i)
    {
      // Should call the visit method,
      //   mutable object.
      sv.visit(obj_container[i]);
    }
  }
};

对于具有两个方法(相对于两个单独的类)的访问者类,容器的for_each方法仍然具有相同的机制。循环是相同的,只是调用一个不同的方法。

那么,有没有办法让一个for_each循环在const-ness上调用适当的访问者基础?

1 个答案:

答案 0 :(得分:1)

不可能有一个可以作为const或非const的非静态成员函数。相反,您可以使用非成员或静态函数模板,并将容器作为参数传递。

struct Container
{
  Object obj_container[LIMIT];

  // C can match either `const Container` or `Container`
  // V can match either `Const_Visitor` or `Mutable_Visitor`
  template<class C, class V>
  static void for_each(C& c, V& v) {
    for (unsigned int i = 0; i < LIMIT; ++i)
    {
      v.visit(c.obj_container[i]);
    }
  }

  void for_each(Const_Visitor& cv) const
  {
    for_each(*this, cv);
  }

  void for_each(Mutable_Visitor& mv)
  {
    for_each(*this, mv);
  }
};