我正在寻找可选 ( sizeof small_optional<T> == sizeof (T)
) 的节省空间的实现。
因此空是使用 T 的一些特殊值编码的,例如
small_optional<int, -1>
要求我从不将 -1 存储在 small_optional 中,因此 -1 可以用作魔术值来确定可选值是否为空。
最佳答案
markable lib 是为这个唯一目的而创建的:
Markable 1.0.0
An alternative to
boost::optional<T>
which does not store an additionalbool
flag, but encodes the 'empty' state insideT
using a special indicated value.Usage
Do you want to store a possibly missing
int
? Can you spare value-1
? You can use it like this:using namespace ak_toolkit; typedef markable<mark_int<int, -1>> opt_int; opt_int oi; opt_int o2 (2); assert (!oi.has_value()); assert (o2.has_value()); assert (o2.value() == 2); static_assert (sizeof(opt_int) == sizeof(int), "");
Do you want to store a possibly missing
std::string
, where 'missing' != 'empty'? Can you spare some string values that contain a null character inside, likestd::string("\0\0", 2)
? This is how you do it:struct string_marked_value // a policy which defines the representaioion of the : ak_toolkit::markable_type<std::string> // 'marked' (special) std::string value { static std::string marked_value() { // create the marked value return std::string("\0\0", 2); } static bool is_marked_value(const std::string& v) { // test if a given value is considered marked return v.compare(0, v.npos, "\0\0", 2) == 0; } }; typedef ak_toolkit::markable<string_marked_value> opt_str; opt_str os, oE(std::string("")); assert (!os.has_value()); assert (oE.has_value()); assert (oE.value() == ""); static_assert (sizeof(opt_str) == sizeof(std::string), "");
虽然不是 Boost 库,但 markable 是在 Boost Software License, Version 1.0. 下获得许可的,甚至从 Performance Considerations 中引用Boosts 自己的可选类型部分:
Performance considerations
[...]
Controlling the size
[...] Therefore, if the size of the objects is critical for your application (e.g., because you want to utilize your CPU cache in order to gain performance) and you have determined you are willing to trade the code clarity, it is recommended that you simply go with type
int
and use some 'magic value' to represent not-an-int, or use something like markable library.
库的背景和思考过程在库作者的以下博客文章中进行了解释:
关于c++ - boost 是否有一个 "compact optional",其中存在由类型的特殊值编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62712790/