这是一个激励性的例子,展示了我的问题:
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();
的情况下初始化?
答案 0 :(得分:1)
在幕后,boost::optional
实现为一个简单的
struct {
bool _present;
T _t;
}
因此,无论您是否使用值显式初始化可选项,此值的存储都已存在,而在C ++中,我们通常不愿意支付我们不需要的内容(例如,检查如果operator->
)的每次通话都有可选项。
开发人员有责任仅尝试访问可选值(如果存在),如documentation中所述:
尝试提取未初始化的可选对象的包含值是未定义的行为(UB)。此实现使用
BOOST_ASSERT
保护呼叫。因此,在提取之前,您应该确保包含的值。
实际上你的代码应该在SIGABRT
断言,你是否在调试模式下运行它?
如果您想避免任何UB风险,可以使用value()
(但您需要将其放在try
区块中)。