Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是惯用的现代C++;对于代数数据类型? 假设,例如,您想在C++中实现电子表格单元格。单元格可以是字符串、数字,也可以是空的。忽略其他情况,比如它是一个公式_C++_Polymorphism_Unions_Variant_Algebraic Data Types - Fatal编程技术网

什么是惯用的现代C++;对于代数数据类型? 假设,例如,您想在C++中实现电子表格单元格。单元格可以是字符串、数字,也可以是空的。忽略其他情况,比如它是一个公式

什么是惯用的现代C++;对于代数数据类型? 假设,例如,您想在C++中实现电子表格单元格。单元格可以是字符串、数字,也可以是空的。忽略其他情况,比如它是一个公式,c++,polymorphism,unions,variant,algebraic-data-types,C++,Polymorphism,Unions,Variant,Algebraic Data Types,在Haskell中,您可以执行以下操作: data Cell=CellStr String | CellDbl Double | None 什么是当前C++中的“最佳实践”?在带有类型指示符的结构中使用联合,或者其他什么?继承 我不得不说,我并不喜欢这种方法,也不认为它是现代的,但它似乎仍然是标准的。 class DoubleCell : public Cell { double value; public: DoubleCell( double v ) : valu

在Haskell中,您可以执行以下操作:

data Cell=CellStr String | CellDbl Double | None
什么是当前C++中的“最佳实践”?在带有类型指示符的结构中使用联合,或者其他什么?

继承

我不得不说,我并不喜欢这种方法,也不认为它是现代的,但它似乎仍然是标准的。
class DoubleCell : public Cell {
    double value;

    public:
    DoubleCell( double v ) : value(v) {}
    double DoubleValue() { return value; }
    ...
};

class StringCell : public Cell {
    std::string value;

    public:
    StringCell( std::string v ) : value(v) {}
    std::string StringValue() { return value; }
    ...
};

class EmptyCell : public Cell {
    ...
};
其中一些缺点是:

  • 在获取实际值时,需要使用不同的函数。这通常涉及到使用
    instanceof
    和强制转换

  • 不同的对象不能直接放入容器,只能作为指针


    • 实现多态性的标准方法是通过虚拟类


      这是一个基本的C++机制。

      一个可能的选项是。或者用自己实现特定的变体类型union@Pixelchemist做一个答案,我将+1。我将使用排序的
      向量双倍和已排序的
      向量字符串。对于给定的单元格坐标,将
      下界
      设置为
      双倍
      ,如果未找到,则对
      字符串
      执行相同操作,否则为
      。绘制屏幕应该非常快,您只需在
      向量中迭代。计算有点混乱,因为它们取决于类型,但您可以将其抽象出来。实际上,我只是作弊,从来没有把不同的类型组合成一个。无论如何,这个问题太宽泛和固执己见了。@MvG不幸的是,haskell的突出显示代码是
      lang hs
      ,而不是
      lang haskell
      。下次要添加Haskell代码的突出显示时,请记住这一点。这只是部分回答了问题。您如何从这样的单元格
      ??中获取值???getValue(){return value;}
      指针语义、动态内存分配和每个单元格的虚拟函数调用对我来说似乎不是一个好主意。模板不会真正起作用(至少在像示例中那样实现时),因为每个单元格的类型需要在编译时知道。我想你可以通过使模板从一个公共基类派生来结合这两种方法,但它的性能开销将与第一种方法相同。@FrankPuffer库的使用只是为了让他们不必自己滚动。在您的示例中,如何从单元格中获取值?直到你知道这只是半个答案,我不认为这个答案应该被删除。这是一个合理的设计解决方案,值得讨论,即使只是说有更好的解决方案。还要注意,有一个标准化建议(原始建议)@filipos在我看来,该建议是有缺陷的,因为它试图强制允许变体为空。我真诚地希望它被拒绝,取而代之的是一个更接近于boost变体的模型。最新版本并不要求这样做。要使用空状态,请将类型
      monostate
      显式添加到类型列表中。确实,在特殊情况下,变体可能会变得无效(不是空的)。@filipos在我看来,它们混合了担忧。可选是一个问题,变体是另一个问题。如果投标人需要可选变量,他可以使用可选变量。变量永远不应该被允许无效,即使在移动之后——它应该只包含一个moved from T。“LEWG反对引入一个显式的附加变量状态,表示它的无效(可能是空的,默认构造的)状态。”当所有项目都是一个概念的专业化,并且所有专业化共享一个公共接口时,多态性是正确的方法。在这个狭窄的范围之外,它只会带来问题,没有“虚拟类”这样的东西。这只是一个不详细的版本,不是吗?
      struct empty_type {};
      using cell_type = boost::variant<std::string, double, empty_type>;
      
      boost::apply_visitor(some_visitor(), cell);