5

我刚刚看了 cppcon 谈论 Bloomberg datum,变体类型使用 IEEE754 格式的冗余来编码存储在 datum 中的类型。

所以我想知道 C++ 标准是否允许实现通过使用相同的技巧更有效地实现 std::optional 。

请注意,这需要有时存储在 optional 中的 double 的二进制表示与传递给构造函数的 double 的二进制表示不匹配。

注意:我关心标准是否允许这样做,我知道大多数/所有实现都不会打扰。

我知道 IEEE754 不是标准强制要求的,但它是允许的并且可以通过实现进行检查。

4

1 回答 1

5

该标准要求,如果您将值存储在 中std::optional,则该值必须能够完全按照存储的方式检索。此外,如果 an被使用,您可以在' 值optional<T>中存储任何 值,而不会让您知道您正在执行此操作。像这样:Toptionaloptional

optional<T> opt = T{};
auto &&val = *opt;
val = <insert value here>; //opt has no idea it has been set.

因此,唯一有效的方法optional<T>可以优化为使用某些值T来表示optional未参与,如果用户不可能使用这些值创建 a T。的 IEEE-754 实现double可以采用任何位模式,并且它们都是合法的(甚至是信号 NaN)。

其他可选类型可以这样做的原因是因为它们与用户有一个隐含的协议,即它们不会将其设置为某些值。std::optional<T>没有这样的协议;T可以存储和检索任何可以假定的值。

现在,如果optional<T>::operator*并且optional<T>::value返回某种代理对象而不是对 的直接引用T,那么这可能是可能的,因为代理可以处理适当的转换。但即便如此,该标准也必须明确指出,尝试将其设置为这些值之一将导致该值采用等效但不同的对象表示。

于 2018-10-22T14:14:53.630 回答