如何在具有公共成员变量的类型中正确使用boost :: optional?

时间:2017-12-04 17:30:01

标签: c++ boost optional

这是一个激励性的例子,展示了我的问题:

struct Foo
{
  int x;
  int y;
};

boost::optional<Foo> opt_foo;

opt_foo->x = 1; // legal
opt_foo->y = 2; // legal

auto foo = opt_foo.get(); // legal (returns valid instance of Foo with x = 1 and y = 2)

if (opt_foo) // false
{
  ...
}

据我所知,为了初始化可选对象,我必须使用boost::optional<Foo> opt_foo = Foo();。然而,我很惊讶地发现,如果它被遗忘,我仍然可以做我标记为合法的所有事情(特别是get())。这是预期的行为吗?有没有办法opt_foo认为自己在没有boost::optional<Foo> opt_foo = Foo();的情况下初始化?

1 个答案:

答案 0 :(得分:1)

在幕后,boost::optional实现为一个简单的

struct {
  bool _present;
  T _t;
}

因此,无论您是否使用值显式初始化可选项,此值的存储都已存在,而在C ++中,我们通常不愿意支付我们不需要的内容(例如,检查如果operator->)的每次通话都有可选项。

开发人员有责任仅尝试访问可选值(如果存在),如documentation中所述:

  

尝试提取未初始化的可选对象的包含值是未定义的行为(UB)。此实现使用BOOST_ASSERT保护呼叫。因此,在提取之前,您应该确保包含的值。

实际上你的代码应该在SIGABRT断言,你是否在调试模式下运行它?

如果您想避免任何UB风险,可以使用value()(但您需要将其放在try区块中)。