基于标志触发成员初始化列表中成员的特定构造函数

Nim*_*Nim 6 c++

我想基于我传递给包含类的构造函数的标志触发成员变量的特定构造函数.

如果我从一个简单的例子开始,这是最简单的:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这样的想法是触发构造函数Astate,但Bboost::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 ? new A(st) : new A(boost::none_t())), _b(st.flag2 ? new B(st) : new B(boost::none_t()))

#2不那么吸引人,因为我试图避免动态内存分配(真正的例子有数十个成员和深层嵌套结构,有更多成员).
#1也没有吸引力,因为我需要构建然后复制.

还有更好的选择吗?

编辑: state由构造中的成员修改,所以state如果没有设置标志,我不想构造一些东西.

Nim*_*Nim 1

看来使用使boost::optional<>事情变得复杂,将其与复制构造方法一起使用似乎会导致调用state基于和基于复制的A&构造函数B- 即使进行了完全优化。

但是,如果我将 的成员C简单地定义为A _aand B _b,则复制构造函数实际上会被优化掉,所以这样做

_a(st.flag1? A(st) : A()), _b(st.flag2? B(st) : B())
Run Code Online (Sandbox Code Playgroud)

实际上显然是让它工作的最佳方法,我只需要解决我在 boost::Optional<> 中使用的其他功能(即初始化与未初始化)。