Шаблон C ++ для константных и неконстантных методов

У меня проблема с дублированием идентичного кода для версий const и не const . Я могу проиллюстрировать проблему с помощью некоторого кода. Вот два примера посетителей, один из которых изменяет посещенные объекты, а другой - нет.

struct VisitorRead 
{
    template <class T>
    void operator()(T &t) { std::cin >> t; }
};

struct VisitorWrite 
{
    template <class T> 
    void operator()(const T &t) { std::cout << t << "\n"; }
};

Вот агрегатный объект - у него всего два элемента данных, но мой реальный код намного сложнее:

struct Aggregate
{
    int i;
    double d;

    template <class Visitor>
    void operator()(Visitor &v)
    {
        v(i);
        v(d);
    }
    template <class Visitor>
    void operator()(Visitor &v) const
    {
        v(i);
        v(d);
    }
};

И функция, демонстрирующая вышеизложенное:

static void test()
{
    Aggregate a;
    a(VisitorRead());
    const Aggregate b(a);
    b(VisitorWrite());
}

Теперь проблема заключается в дублировании ] Aggregate :: operator () для версий const и не const .

Можно ли как-то избежать дублирования этого кода?

У меня есть одно решение:

template <class Visitor, class Struct>
void visit(Visitor &v, Struct &s) 
{
    v(s.i);
    v(s.i);
}

static void test2()
{
    Aggregate a;
    visit(VisitorRead(), a);
    const Aggregate b(a);
    visit(VisitorWrite(), b);
}

Это означает, что не требуется ни Aggregate :: operator () , ни дублирования. . Но меня не устраивает тот факт, что visit () является общим без упоминания типа Aggregate .

Есть ли способ лучше?

16
задан paperjam 3 October 2019 в 10:11
поделиться