Mar*_*ťko 4 c++ option-type c++17
我正在编写一个代表按钮的类。该按钮可能有也可能没有各种属性,例如上面写的文本、快捷方式、纹理或平面颜色填充。因此,例如,如果此按钮没有任何纹理集,则跳过纹理绘制过程。
我的第一个解决方案是使用虚构的默认值,这表示给定的属性未使用(如果颜色的 alpha 值为 0,则将跳过颜色填充绘图等)。
我的其他选择是使用新添加的 std::Optional ,这会更清晰且更易于使用。
以下是提到的 2 个示例:
class Button {
void draw() {
if (fill)
drawRectangle(*fill);
if (sprite)
drawSprite(*sprite);
if (font)
drawText(name, *font);
}
std::optional<std::string> font;
std::optional<std::string> sprite;
std::optional<Color> fill;
}
class Button {
void draw() {
if (fill.alpha != 0)
drawRectangle(fill);
if (sprite != "")
drawSprite(sprite);
if (font != "")
drawText(name, font);
}
std::string font;
std::string sprite;
Color fill;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下使用 std::Optional 的优点和缺点是什么?我主要感兴趣的是内存使用和开销差异。
另外,我是否应该调用 value() 并捕获异常,而不是使用 if 来检查可选是否包含值?
就开销而言,它主要以空间的形式存在。optional总是占用它存储的任何内容,加上一个布尔值,再加上任何额外的填充来进行对齐。例如,std::string通常实现为具有 8 字节对齐的 24 字节。Anoptional<string>将为 25 字节,但由于对齐,最终将变为 32 字节。对于原始类型(int 或 enum),通常会将所需的存储量从 4 字节增加到 8 字节或类似的值。
就性能而言,在这种情况下,缓存效果之外不会有任何差异(如果优化器很聪明)。将 astd::string与空字符串文字进行比较可能会优化为调用std::string::empty(您可能应该这样写),这只是检查整数是否为零,这与您的比较相同Color,这基本上与检查布尔值是否为零。
这就是说我确实喜欢optional;我认为它更清楚地传达了代码的意图。然而,如果你有非常明显的哨兵值,那么它的价值可能就不那么高了。
在某些情况下,您可以通过紧凑的可选选项鱼与熊掌兼得: https: //github.com/akrzemi1/compact_Optional。它具有与常规选项相同的外部接口,但是您给它一个哨兵值,它使用该哨兵来存储丢失的状态。但可能不适用于所有课程。