是否允许将空值插入C ++ std :: map?

时间:2013-02-20 19:20:40

标签: c++ std stdmap

我正在考虑一种棋盘设计,并希望按照以下方式做一些事情:

typedef std::map <std::string, CheckerPiece> MapType;
MapType CheckerBoard;

CheckerBoard.insert({"a1", null});

这是允许的,还是有办法做类似的事情?我的想法是,我想保持一个电路板状态,同时将CheckerPiece对象从一个位置移动到另一个位置。

编辑: 同样,是否可以执行以下操作:

CheckerBoard.insert({"a1", new CheckerPiece()});

4 个答案:

答案 0 :(得分:8)

您的地图不包含CheckerPiece指针,因此您尝试执行的操作甚至不会编译,除非您有CheckerPrice的隐式构造函数,它将指针作为参数。这忽略了nullC++中没有任何意义的事实。假设您的意思是NULLnullptr,则无法插入其中任何一个或

的结果
new CheckerPiece()

进入你的地图,期间。上面的表达式返回指向CheckerPiece的指针。

C ++没有类型的空值概念(除非你专门设计一个)。解决方法是使用包装类型为您提供可选的语义,即允许您检查某些内容是否已“设置”。一个例子是boost::optional

这是一个未经测试的例子:

#include <boost/optional.hpp>

boost::optional<CheckerPiece> piece;

if (piece) {
  // piece is not set, we should never get here
}

piece.reset(CheckerPiece( constructor arguments...));

if (piece) {
  // piece is set, use it!
  piece.move();
}

答案 1 :(得分:1)

CheckerPiece看起来像什么?最明显的解决方案 将增加一个对应的额外的可能性 没有一块。件确实没有任何行为,并且 你不需要它们;你真的只需要 关于正方形状态的信息:红色,黑色或 空的,加冠的(如果空的话会被忽略)。

我可能会补充说,将棋盘格作为地图可能不是 也是最有道理的解决方案。我会选择类似的东西:

CheckerPiece board[10][10];

(或CheckerPiece board[N][N],其中N是模板 参数,如果你想支持本地变体,而不仅仅是 国际标准检查员)。

答案 2 :(得分:0)

如果要使用指针/堆分配的CheckerPieces,则必须定义地图以使用CheckerPiece*而不是CheckerPiece。在C ++中没有null这样的东西,因为“这里没有对象”的价值。在不使用第三方库的情况下指示可选对象的规范方法是使用指针并在可选元素不存在时将其设置为nullptr

我可能会使用boost::optional表示CheckerPiece可能会或可能不会在给定位置,除非您有理由不能使用第三方库。

答案 3 :(得分:0)

更改您对Board的定义。

董事会或董事会状态是<checker piece, location>的集合。不在此容器中的任何纸板位置都被视为空。任何未处于董事会状态的检查员都已被捕获。

使用这个概念,不需要null检查器片段,也不需要将检查器片段与NULL进行比较。

当计划移动或创建移动历史记录时,您可以使用板状态容器。

我建议使用给定的板状态创建绘制板的功能。这解决了在板状态容器中每次移动时尝试表示实际板的问题。