c++ - 使用 std::optional<int> 是否与使用 int 一样有效?

标签 c++ performance option-type c++14 boost-optional

我有一个四/八叉树数据结构。我将一个单元格的子索引/ptrs 存储在一个数组中。数组中的每个位置都代表一个 child 相对于其 parent 的位置,例如二维:

// _____________
// |     |     |
// |  2  |  3  |
// |_____|_____|
// |     |     |
// |  0  |  1  |
// |_____|_____|
// for each cell, 4 children are always stored in row-major order
std::vector<std::array<Integer,4>> children;

我知道最大子节点数是 Integer 的值的子集。类型可以代表。因此,我可以通过使用像 -1 这样的“魔法”值来识别单元格是否缺少 child 。对于 Integer = int , 或 std::numeric_limits<unsigned>::max()对于 Integer = unsigned .这是std::optional<Integer>不能假设。

据我所知,魔法值的这种用法是std::optional 存在的理由之一。 .尽管如此,我还是担心std::vector<std::optional<int>> 的性能。在内部循环中。

所以,

  • 请问std::vector<std::optional<int>>的表现比std::vector<int>更差? (我已经在比较“不存在”的值了)。

  • 或者,可以执行std::optional进行优化以提供与原始 int 相同的性能?以及如何?

混合 std::optional在我的数据结构中我的函数和魔法值的返回类型听起来是一个非常糟糕的主意。我更喜欢保持一致并使用其中一个(至少在相同的上下文中)。虽然我可以重载执行与魔数(Magic Number)比较的函数:

template<T> bool is_valid(const T& t) { 
  return /* comparison with magic value for t */; 
}

对于可选类型。

最佳答案

std::optional将需要额外的存储空间并在缓存中放入更少的值(看来您已经知道这样做的原因)。

我认为在数据结构内部存储的值与公共(public) API 公开的值不同,只要内部表示对用户完全隐藏即可。

此外,我建议您将魔数(Magic Number)隔离为一对inline转换函数。

编译器应该通过在您忘记时生成类型错误来帮助您记住始终如一地使用转换函数。您甚至可以为 int 使用瘦结构包装器。在您的内部数据结构中,确保不存在隐式转换(或定义用户定义的转换)。

class CompressedOptionalUInt
{
    static const unsigned SENTINEL_MISSING = std::numeric_limits<unsigned>::max();
    unsigned value;

public:
    CompressedOptionalUInt(std::optional<unsigned> val) : value(!val? SENTINEL_MISSING: *val) {}
    operator std::optional<unsigned>() const { ... }
};

然后使用 std::array<CompressedOptionalUInt> .

将其制作成模板,只需为每种类型定义哨兵,应该非常简单。

关于c++ - 使用 std::optional<int> 是否与使用 int 一样有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17324286/

相关文章:

如果对象是原型(prototype)化的并且是从文字创建的,则访问对象字段的 Javascript 性能

ios - Swift:测试 nil 的可选值

c++ - 同步文件,删除相同数据

c++ - QWebView,如何判断这个链接是否是新窗口?

java - 绘制缓冲图像时 Java 2D 的性能问题

java - java 8 中的 Lambda 表达式(使用 java.util.Optional 在 HashMap 中进行空检查)

c++ - 带有 initializer_list 的可选构造函数

c++ - 如何在类成员函数中添加错误检查?

c++ - 使用 cocoapods 在 iOS 上集成 GoogleCloudMessaging

Java:如何解压缩内存使用率较低的文件(zip或tar.gz)?