Я пытаюсь решить следующую проблему. У меня есть вектор (на самом деле это настраиваемая структура, но вектор является достаточно хорошей заменой этой проблеме) указателей на пользовательский класс A
. Класс A
может фактически хранить указатель type_a
или указатель type_b
(эти типы совершенно разные и не связаны друг с другом). Прямо сейчас это реализовано путем сохранения обоих параметров, установив их на NULL
, а затем с букетом if/else
утверждений, чтобы проверить, какой тип он является, и выполнить соответствующие действия.Вариантное переменное взаимодействие с невариантным типом
class A {
public:
A() : p1(NULL), p2(NULL) {}
type_a * p1;
type_b * p2;
};
std::vector<A *> v;
...
if (v[0]->p1 != NULL) { /* do this */ }
else if (v[0]->p2 != NULL) { /* do that */ }
Я планирую добавить больше указателей на класс A
и так выше, начинает становиться хлопот. Решение, которое я в настоящее время пытаюсь сделать работу использует boost::variant
вместо того, чтобы иметь:
class A {
public:
boost::variant<type_a*, type_b*> p;
};
Проблемы я столкнулся, хотя, является то, что один из моих действий включает вызов функции, которая будет присваивать некоторые значения к переменная в зависимости от типа p
У меня есть. Это то, что сейчас и соответствующая process_stuff
функция вызывается в одном из приведенных выше утверждений if/else
:
class B { /*...*/ };
void process_stuff(type_a * p, B * b) {
b->m_var = p->fn1();
}
void process_stuff(type_b * p, B * b) {
b->m_var = p->fn2();
}
Я не могу получить эту работу с boost::static_visitor
, так как (насколько я понимаю) я не могу имеют невариантный тип в качестве аргумента при двоичном посещении, а также я не могу создать константу operator()
, чтобы сделать вторую переменную членом класса посетителя и изменить ее внутри operator()
с унаследованным посещением. Поэтому я смущен, как преобразовать вышеуказанную функцию process_stuff
, чтобы играть вместе с boost::variant
.
Btw Я не привязан к boost::variant
и принимал другие решения.
Короткий ответ: если вы не можете каким-либо образом объединить типы, как вы делаете гетерогенную коллекцию, это, вероятно, будет уродливым и неуклюжим. –
К сожалению, я не могу унифицировать типы. Я думаю, что все это сработало бы неплохо, если бы я мог, например. имеют не-const 'operator()' в 'static_visitor'. – eddi