【问题标题】:C++ avoiding code duplication for const and non-const visitationC++ 避免 const 和非常量访问的代码重复
【发布时间】:2011-03-09 21:29:34
【问题描述】:

我有一个类应该为每个成员变量调用一个访问者方法。像这样的:

class A{
    int a, b, c;

public:
    void accept(Visitor &visitor){
        visitor.visit(a);
        visitor.visit(b);
        visitor.visit(c);
    }
};

我怎样才能得到void accept() const 方法与相同的代码没有代码重复?

重复的明显解决方案是添加一个方法:

void accept(Visitor &visitor) const {
    visitor.visit(a);
    visitor.visit(b);
    visitor.visit(c);
}

那个方法正是我想要的意思,但我想避免代码重复。使用这两种方法的原因是能够通过“阅读”访问者来读取变量,并且可以很好地使用accept 方法const。然后非常量 accept 可以用于“编写/更新”访问者。

【问题讨论】:

  • 代码重复发生在哪里。信息不足。
  • visit 的签名是什么?如果是 const,则不需要非 const accept。如果不是,那么这个 accept 不能是 const。
  • 你不能在当前的accept 方法上加一个const 吗?为什么需要一个非常量版本的接受?
  • @Beta:visit() 可能为const 和非const 过载。
  • @Beta: Visitor::visit 可能在 const int&int& 参数上重载,后者可能会修改访问的内容。不确定这是否明智,但提问者当前的重复代码允许这样做。

标签: c++ const-correctness visitor-pattern


【解决方案1】:

您可以创建一个类静态模板帮助函数,该函数将根据您提供给它的this 指针的类型推断常量。像这样:

class A{
    int a, b, c;

public:

    void accept(Visitor &visitor){
        acceptImpl(*this, visitor);
    }
    void accept(Visitor &visitor) const{
        acceptImpl(*this, visitor);
    }

private:
    template<typename t_A>
    static void acceptImpl(t_A& aObj, Visitor &visitor)
    {
        visitor.visit(aObj.a);
        visitor.visit(aObj.b);
        visitor.visit(aObj.c);
    }
};

【讨论】:

    【解决方案2】:

    模板助手:

    class A{
        int a, b, c;
    
    private:
        template <typename T>
        static void do_visiting(T &self, Visitor &visitor) {
            visitor.visit(self.a);
            visitor.visit(self.b);
            visitor.visit(self.c);
        }
    public:
        void accept(Visitor &visitor) {
            do_visiting(*this, visitor); // calls do_visiting<A>
        }
        void accept(Visitor &visitor) const {
            do_visiting(*this, visitor); // calls do_visiting<const A>
        }
    };
    

    【讨论】:

      猜你喜欢
      • 2012-01-28
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      相关资源
      最近更新 更多