gpt4 book ai didi

c++ - 在异常情况下使用额外的状态信息扩展基本类型

转载 作者:行者123 更新时间:2023-11-28 04:38:14 25 4
gpt4 key购买 nike

我正在寻找一种方法来扩展 int一些状态信息的变量,这些信息很少使用,大多数时候它只是重要的 int 值。这就是为什么我想避免使用带有额外 bool 成员的结构。

相关附加属性最多为 5 到 6 个附加属性,例如 NULL、UNDEFINED、NAN、MISSING,其中只有一个可以为真。

想法:

  • int 指针是为一个附加属性执行此操作的一种方法:nullptr 是 int 变量可以采用的一个附加值。但在这种情况下,我不能有更多的异常状态。

  • 另一种选择是使用一些我不希望使用的魔法值,例如 UNDEFINED = std::numeric_limits<int>::min()MISSING = std::numeric_limits<int>::min()+1等等。

问题:是否有更好的方法(需要最少的额外内存)?

子问题:如果我可以在编译期间确定该值是否属于异常(exception)情况,是否有一种不使用额外内存的好方法来做到这一点?

最佳答案

最好的替代方案是不使用整数,而是使用其他类型——您建议使用 int* 也属于此类。这种包装器类型当然可以重载各种运算符,以便于访问底层整数值。定义一个新类型(或利用现有的标准库类型)是内存的最佳条件,因为您可能只会将每个整数的大小加倍(例如,现在您可能有整数 + 枚举(由 int 或更小的支持)+ 可能的填充)。根据您的整数大小,即使是指针也可能有更多的内存开销。

如果只有少数整数具有额外的状态并且这些整数不会被复制或移动,那么您可以将状态存储在外部,从整数标识到状态的映射中。 IE。我们使用指向整数对象的指针作为键。对于每个具有额外状态的整数,此映射的内存开销将比替代方案高得多,但根据您的使用模式,这可能是最紧凑的解决方案。显然,这里存在内存泄漏的机会,因此您应该将整数包装在自定义类型中,该类型在销毁时删除任何映射条目。大致是这样的:

enum class IntStatus { IS_NAN, IS_MISSING };

class IntWithExternalStatus {
public:
explicit IntWithExternalStatus(int x = 0) : m_value{x} {}
explicit IntWithExternalStatus(IntStatus s) : m_value{} { s_status.insert({this, s}); }
~IntWithExternalStatus() { m_status.erase(this); }

operator int& () { return m_value; }
operator int () const { return m_value; }
bool is_valid() const { return s_status.find(this) == s_status.end(); }
bool is_nan() const {
auto it = s_status.find(this);
return it != s_status.end() && it->second == IntStatus::IS_NAN;
}
bool is_missing() const {
auto it = s_status.find(this);
return it != s_status.end() && it->second == IntStatus::IS_MISSING;
}
private:
static std::unordered_map<IntWithExternalStatus const*, IntStatus> s_status;
int m_value;
};

也许所有这些额外的类型都是不必要的过度复杂化。如果您只有几个整数变量需要额外的状态,那么为状态创建一个单独的变量可能是最简单的。例如:

int m_foo;
int m_bar;
IntStatus m_foo_status;
IntStatus m_bar_status;

由于对齐问题,这可能会导致比定义组合的 int-and-status 对象更紧凑的内存布局。

为您的状态使用特殊值是一种没有空间开销的简单解决方案,但有一个巨大的缺点:对这些整数的任何算术都会删除状态并产生虚假值。您将需要大量的运行时检查来防止这种情况发生,最好将其封装在一个单独的类型中。

关于编译时子问题,这取决于您对内存使用的定义。例如。您可以使用根据编译时值选择 intInvalidInt 类型的模板元编程,其中 InvalidInt 是一种空对象模式。但是,这将为所有实例化模板生成专用代码。特别是,使用您的 status-ints 的代码也必须被模板化。如果您同时拥有许多具有相同状态的状态整数,这可能会减少总内存使用量,但在其他情况下不太可能有帮助。

关于c++ - 在异常情况下使用额外的状态信息扩展基本类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50820386/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com