У меня проблема с дублированием идентичного кода для версий 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
.
Есть ли способ лучше?