Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;避免常量和非常量访问的代码重复_C++_Const Correctness_Visitor Pattern - Fatal编程技术网

C++ C++;避免常量和非常量访问的代码重复

C++ C++;避免常量和非常量访问的代码重复,c++,const-correctness,visitor-pattern,C++,Const Correctness,Visitor Pattern,我有一个类,它应该为每个成员变量调用一个visitor方法。大概是这样的: class A{ int a, b, c; public: void accept(Visitor &visitor){ visitor.visit(a); visitor.visit(b); visitor.visit(c); } }; 如何使用相同的代码获得void accept()const方法而不需要代码重复 复制的明显解决方案是

我有一个类,它应该为每个成员变量调用一个visitor方法。大概是这样的:

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
可以用于“写入/更新”访问者。

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

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);
    }
};
A类{
INTA、b、c;
公众:
无效接受(访客和访客){
acceptImpl(*本,访客);
}
无效接受(访客和访客)常量{
acceptImpl(*本,访客);
}
私人:
模板
静态void acceptImpl(t_A&aObj、访问者和访问者)
{
访客访问(aObj.a);
访客访问(aObj.b);
访客访问(aObj.c);
}
};
模板帮助程序:

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>
    }
};
A类{
INTA、b、c;
私人:
模板
静态无效访问(T&self、访客和访客){
访问者访问(self.a);
访问者访问(self.b);
访问者访问(self.c);
}
公众:
无效接受(访客和访客){
do_Visition(*这个,访客);//呼叫do_Visition
}
无效接受(访客和访客)常量{
do_Visition(*这个,访客);//呼叫do_Visition
}
};

代码复制发生在何处。信息不足。
访问的签名是什么?如果它是常量,那么就不需要非常量
accept
。如果不是,那么这个
accept
不能是常量。你不能在当前的
accept
方法上加一个
const
?为什么需要非常量版本的accept?@Beta:可能是
const
重载了
visit()
,而非
const
@Beta:
Visitor::visit
可以在
const int&
参数上重载,后者可能会修改所访问的对象。不确定这是否明智,但提问者当前的重复代码允许这样做。