Конструктор триггера для члена в списке инициализации члена на основе флага

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

Проще всего, если Я начну с тривиального примера:

#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 не одного типа. Может ли кто-нибудь придумать элегантный способ обойти это?

Я знаю два решения:

  1. Копировать конструкцию, т.е.

    _a (st.flag1? A (st): A (boost :: none_t ())) , _b (st.flag2? B (st): B (boost :: none_t ()))

  2. Используйте указатели вместо boost :: optional <> , затем

    _a (st.flag1 ? новый A (st): новый A (boost :: none_t ())), _b (st.flag2? new B (st): new B (boost :: none_t ()))

# 2 не так привлекателен, поскольку я пытаюсь избежать динамического распределения памяти (в реальном примере есть десятки элементы и глубоко вложенные структуры с большим количеством элементов).
№1 также не очень привлекателен, так как мне нужно было бы построить, а затем скопировать.

Есть ли лучшая альтернатива?

РЕДАКТИРОВАТЬ : состояние изменяется членами при построении, поэтому я не хочу создавать что-то с состоянием , если флаг не установлен.

6
задан mskfisher 2 November 2011 в 16:08
поделиться