在C++中什么也不表示

在C++中什么也不表示,c++,C++,我的情况是,我有一个std::vector,但我希望其中一些double是空的/不存在的。这是如何在C++中完成的?我们可以放心地假设,就我的目的而言,所有正常的双精度都不是负的 我应该让-1或一些负数表示什么也不表示吗?听起来不太优雅 我应该创建一个包含nothing bool成员的双类吗?这可能行得通,但看起来相当冗长和丑陋 我应该创建一个Double类并创建一个NoDouble:public Double子类吗?听起来更糟 如果您有任何想法,我们将不胜感激。如果您有IEEE浮点算法,请使用

我的情况是,我有一个std::vector,但我希望其中一些double是空的/不存在的。这是如何在C++中完成的?我们可以放心地假设,就我的目的而言,所有正常的双精度都不是负的

我应该让-1或一些负数表示什么也不表示吗?听起来不太优雅

我应该创建一个包含nothing bool成员的双类吗?这可能行得通,但看起来相当冗长和丑陋

我应该创建一个Double类并创建一个NoDouble:public Double子类吗?听起来更糟


如果您有任何想法,我们将不胜感激。

如果您有IEEE浮点算法,请使用std::numeric\u limits::quiet\u NaN作为零值。要检查d是否为空,请使用isnand。还有d!=只有当d为NaN时,d才为真。NaN的问题是,当进行有缺陷的计算时,例如将零除以零或从负数中取平方根时,可能会得到它。使用NaN的任何计算结果也将使用NaN

若您碰巧使用了boost,那个么您可以使用boost::optional,它会在NaN端添加其他级别的not可用性。然后你有两种糟糕的状态:无效号码和丢失号码。Boost包含很多有用的库,所以无论如何它都是值得使用的工具

如果您需要一些可能的原因来解释为什么它不存在,那么请使用特殊的易出错类而不是double。Fallible是巴顿和纳克曼发明的,他们是广受赞誉的 科学与工程C++书籍< /P>
你提到可能没有负数。在这种情况下,将double封装到类中。您拥有的不是技术上正常的双精度,因此您的类可以对其进行限制

可以使用std::vector。空指针表示空插槽或值。

您要做的是保持向量不变,但也要使用bool向量,然后将其包装到类中

在体面的编译器上使用bool向量应该优化为每布尔1位,这样就可以解决空间问题

class MyNullable {
public:
  double value;
  bool is_null;  
};

class NullableDoubles {
public:
  std::vector<double> values;
  std::vector<bool> nulls;
  void push_back(double d, bool is_null) {
    values.push_back(d);
    nulls.push_back(is_null);
  }
  MyNullable GetValue(int index) {
    MyNullable result;
    result.value = values[index];
    result.is_null = nulls[index];
    return result;
  }
  bool IsNull(int index) { return nulls[index]; }
  bool MakeNull(int index) { nulls[index] = false; }
};
我相信你可以看到valuenot pun的用意,即在一两个模板中包装这些内容,然后制作任何内容的可空列表

template <class T>
class NullablesClass {
public:
  std::vector<T> values;
  std::vector<bool> nulls;
  void push_back(T d, bool is_null) {
    values.push_back(d);
    nulls.push_back(is_null);
  }
  MyNullable GetValue(int index) {
    MyNullableT<T> result;
    result.value = values[index];
    result.is_null = nulls[index];
    return result;
  }
  bool IsNull(int index) { return nulls[index]; }
  bool MakeNull(int index) { nulls[index] = false; }
  T GetValue(int index) { return values[index]; }
};

我希望这可以做到。这似乎是能够使用所有可能的双精度值并在使用最少内存和最佳内存对齐时知道它是否为NULL的最佳方法。向量是C++库中的一个专门化模板,因此,您应该只为每个BooL得到1位。

STD::vector是一种选择。如果我有像汽车这样的其他课程呢?然后,我是否应该在Car中创建一个NAN成员?Boost的类是一个很好的方法,可以获得与使用bool成员创建类相同的效果,并且它提供了清晰的语法。@DavidSchwartz Boost optional看起来有点像是一种不同的方法,并且不太容易使用nullptr(如果没有)或not nullptr(如果没有)。如果我错了,请纠正我的错误。@user2015453:unique\u ptr也被设计为使用堆,wheras boost::optional只是一个类似于double本身的值。但这改变了复制和析构函数等所有内容的语义。这是一种用氢弹杀死蚂蚁的方法。@DavidSchwartz智能指针可以让它简单得多,对吗?那么就不需要任何特殊的复制/移动/销毁了?@user2015453:智能指针会比原始指针好,但那只是稍微小一点,根本不需要动态分配。Boost.Optional是一个完全可用的轻量级解决方案…不允许您区分不存在的结果和应该存在但在计算过程中被某些问题破坏的结果。Imho类似boost::optional的东西是唯一安全的方法。这也是我想到的第一个想法。@us2012当您还想从列表中找到该值不可用的原因时,则optional也不足。在这种情况下,你需要容易犯错。查一查。遗憾的是,boost没有包含一个。但是它比您的解决方案要短一点。使用可选选项,您可以有“nothings”和“NaN”。@us2012好的,您是对的,我将它们添加为答案的备选选项:个人而言,我会选择Boo::可选的,但是+1,对于一个罕见的有效使用STD::对于内存位置,在同一个类中保持紧密相关的信息通常是明智的,而不是在几个大小相等的容器之间进行拆分。C++具有可空性,它基本上是布尔标记和T。对齐可能会导致每个项浪费7个字节,但这不是什么大问题,除非向量很大。@doug65536:这正是boost::optional的功能。