C ++ избегая дублирования кода для постоянных и неконстантных посещений - PullRequest
7 голосов
/ 10 марта 2011

У меня есть класс, который должен вызывать метод посетителя для каждой переменной-члена. Примерно так:

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 можно будет использовать для «записи / обновления» посетителей.

Ответы [ 2 ]

13 голосов
/ 10 марта 2011

Вы можете создать вспомогательную функцию статического шаблона класса, которая будет выводить константу в зависимости от типа указателя 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 голосов
/ 10 марта 2011

Помощник по шаблонам:

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