c – 使用std :: optional是否像使用int一样有效?
我有一个四/八叉树的数据结构.我将一个单元格的子索引/ ptrs存储在数组中.阵列中的每个位置表示一个孩子相对于其父母的位置,例如,在2D中:
// _____________ // | | | // | 2 | 3 | // |_____|_____| // | | | // | 0 | 1 | // |_____|_____| // for each cell,4 children are always stored in row-major order std::vector<std::array<Integer,4>> children; 我知道最大数量的孩子是Integer类型可以表示的值的一个子集.因此,通过使用Integer = int或Integer = unsigned的std :: numeric_limits< unsigned> :: max(),可以识别单元格是否缺少一个小孩.这是std :: optional< Integer>不能假设 据我所知,魔术值的使用是std :: optional的存在理由之一.不过,我担心std :: vector< std :: optional< int>>的性能.在内圈. 所以, >将会执行std :: vector< std :: optional< int>>比std :: vector< int> (我已经在比较“不存在”的价值). 在我的数据结构中,我的函数和魔术值的返回类型混合std :: optional听起来是一个非常糟糕的主意.我更喜欢保持一致,并且使用一个或另一个(至少在同一个上下文中).虽然我可以重载与魔术数字进行比较的功能: template<T> bool is_valid(const T& t) { return /* comparison with magic value for t */; } 用于可选类型. 解决方法
std :: optional将需要额外的存储空间,并将较少的值安装到缓存中(看来您已经知道了这个原因).
只要内部表示完全被用户隐藏,我们认为在公开API公开的数据结构中内部存储不同的值不是错误的. 此外,我建议您将魔术数字隔离成一对内联转换功能. 编译器应该帮助您记住一直使用转换函数,如果您忘记了生成类型错误.您甚至可以在内部数据结构中为int使用精简的struct wrapper,以确保不存在隐式转换(或定义用户定义的转换). 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> ;. 把它放在模板中,只需要为每个类型定义哨兵,应该是非常简单的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |