Я хотел бы запустить конкретный конструктор для переменной-члена на основе флагов, которые я передаю конструктору содержащего класса.
Проще всего, если Я начну с тривиального примера:
#include <boost/optional.hpp>
#include <boost/none.hpp>
#include <boost/utility/typed_in_place_factory.hpp>
struct state
{
bool flag1;
bool flag2;
int value;
};
class A
{
public:
A() : _a() {}
A(boost::none_t none) : _a() {}
A(state& st) : _a(st.value) {}
A(const A& copy) : _a(copy._a) {}
private:
boost::optional<int> _a;
};
class B
{
public:
B() : _b() {}
B(boost::none_t none) : _b() {}
B(state& st) : _b(st.value) {}
B(const B& copy) : _b(copy._b) {}
private:
boost::optional<int> _b;
};
class C
{
public:
C() : _a(boost::none_t()), _b(boost::none_t()) {}
C(state& st) :
_a(st.flag1 ? st : boost::none_t()),
_b(st.flag2 ? st : boost::none_t())
{}
private:
boost::optional<A> _a;
boost::optional<B> _b;
};
int main(void)
{
state f = { true, false, 10 };
C c(f);
return 0;
}
Итак, идея состоит в том, чтобы запустить конструктор для A
с состоянием
, но B
с boost :: none_t
.
Приведенный выше код не компилируется, потому что тернарный оператор ожидает одного и того же типа для обеих возможностей, а state
и boost :: none_t
не одного типа.
Может ли кто-нибудь придумать элегантный способ обойти это?
Я знаю два решения:
Копировать конструкцию, т.е.
_a (st.flag1? A (st): A (boost :: none_t ())) ,
_b (st.flag2? B (st): B (boost :: none_t ()))
Используйте указатели вместо boost :: optional <>
, затем
_a (st.flag1 ? новый A (st): новый A (boost :: none_t ())),
_b (st.flag2? new B (st): new B (boost :: none_t ()))
# 2 не так привлекателен, поскольку я пытаюсь избежать динамического распределения памяти (в реальном примере есть десятки элементы и глубоко вложенные структуры с большим количеством элементов).
№1 также не очень привлекателен, так как мне нужно было бы построить, а затем скопировать.
Есть ли лучшая альтернатива?
РЕДАКТИРОВАТЬ : состояние
изменяется членами при построении, поэтому я не хочу создавать что-то с состоянием
, если флаг не установлен.