我需要一个整数的向量,在这里我可以区分0和-0.到目前为止,我已经想到了为这个特殊情况定义一个新的类,叫做zero_int。
然而,现在我不能把普通整数和zero_int都推到同一个向量中去.解决方案std::variant的大小为8 Bytes,而我需要保留每个变量的大小为4 Bytes.定义一个虚拟基类my_int,并将zero_int设置为它的派生类,使zero_int的大小增加到32 Bytes...
我知道可以使用类似于 "虚拟基类 "的东西。vector<void*>
但我不知道怎么做... - 还有,指针向量中的指针所指向的对象在内存中是连续的吗?- 在这种情况下,这很重要。
如果有任何关于如何解决这个问题的建议,我将感激不尽。
解决方法std::variant有8个字节的大小,我需要保留每个变量的4个大小。
这是不可能的,除非你不介意失去一个可能的非零的 int
值,这就给我们带来了 "显而易见 "的解决方案:将0视为-0,每一个正数都是自己的负数。
这就给我们带来了一个 "显而易见 "的解决方案:把0看作是-0,把每一个正数看作是它本身减一。
vec[i]: -5 -4 -3 -2 -1 0 +1 +2 +3 +4 +5
my "value": -5 -4 -3 -2 -1 -0 +0 +1 +2 +3 +4
(或者反过来做,这样可以让你在正数和负数范围内保持对称,随你喜欢。)
让任何封装你的向量的类以任何适合你的项目的方式处理这个 "映射"。
指针向量中的指针所指向的对象在内存中是连续的吗?
不是。
你不希望在这里有更多的间接性。
有人会建议使用浮点数,因为IEEE 754支持带符号的零。然而,我认为在任何情况下,用浮点来表示实数都会带来更多的问题,而不是解决问题。
我会考虑使用无符号类型,并将最上面的位显式管理为符号位。
class my_int {
public:
my_int(int v) { set(v); }
explicit operator int() const { return get(); }
bool is_negative() const { return value & sign_bit; }
private:
const static unsigned sign_bit =
1u << (std::numeric_limits<unsigned>::digits - 1);
unsigned value;
void set(int v) { value = v < 0 ? (-v) & sign_bit : v;
}
int get() const { return value & sign_bit ? -(value & ~sign_bit) : value; }
};
注意: 已经写好了,但还没有测试