c++ - boost 是否有一个 "compact optional",其中存在由类型的特殊值编码?

标签 c++ boost stdoptional

我正在寻找可选 ( 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 additional bool flag, but encodes the 'empty' state inside T 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, like std::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/

相关文章:

C++ 控制台应用程序,SetWindowsHookEx,永远不会调用回调

c++ - 可以将 std::getline() 与移出的 std::string 一起使用吗?

c++ - C++ 中的矩形二维字符数组

c++ - 传递将模板参数作为参数默认为 NULL 的 boost::function

c++ - 需要在 VS2013 x64 中工作的 jpeglib-turbo 示例

c++ - 为 Rad Studio 更新 boost 库

sorting - boost 弹性聚集结果

c++ - 是否可以将对象设置为空?

c++ - std::optional::value_or() - 惰性参数评估