使用std :: optional vs." unused / default"值

时间:2017-04-20 19:30:03

标签: c++ optional c++17

我正在写一个代表按钮的类。此按钮可能具有或不具有各种属性,如写在其上的文本,快捷方式,纹理或平面颜色填充。因此,例如,如果此按钮没有任何纹理集,则跳过纹理绘制过程。

我的第一个解决方案是使用组合默认值,表示给定属性未使用(如果颜色的alpha值为0,则会跳过颜色填充图形等。)

我的其他选择是使用新添加的std :: optional,这将更清晰,更简单易用。

以下是上述两个例子:

ch1 = (char)(ch1+1)

在这种情况下,使用std :: optional的优点和缺点是什么?我最感兴趣的是内存使用和开销差异。

我也应该这样做,而不是使用if检查可选项是否包含值,调用value()并捕获异常?

2 个答案:

答案 0 :(得分:4)

就开销而言,它主要是空间形式。 optional总是占用它存储的任何内容,加上一个布尔值,加上任何额外的填充以使对齐工作。例如,std::string通常实现为24字节,8字节对齐。然后optional<string>将是25个字节,但由于对齐,它将最终为32个字节。对于基本类型(int或enum),它通常会将所需的存储空间从4到8个字节加倍,或类似的东西。

就性能而言,在这种情况下,缓存效果之外没有区别(如果优化器是智能的)。将std::string与空字符串文字进行比较可能会优化为对std::string::empty的调用(您应该以这种方式编写),这只是检查整数是否为零,这与您对Color的比较,这与检查布尔值是否为零基本相同。

那说我喜欢optional;我认为它更清楚地传达了代码的意图。但是,如果你有非常明显的哨兵价值,那么它可能不那么有价值。

在某些情况下,您可以使用紧凑的可选项来获取蛋糕并使用它:https://github.com/akrzemi1/compact_optional。它具有与常规可选项相同的外部接口,但是您给它一个sentinel值,它使用该sentinel来存储缺失状态。但是可能不适合所有课程。

答案 1 :(得分:1)

虽然std :: optional可能会产生额外布尔值的开销,但它在这里也有一个描述性的目的:它完全表达了你试图放入代码的概念,这使得这段代码直接向读者展示了什么是继续因为这是UI,并且布尔开销相对较小,我会说它去吧。

我对std :: optional仅用于函数返回的声明提出质疑。这将是荒谬的限制。