【问题标题】:Can I avoid propagating this template up in my design?我可以避免在我的设计中传播这个模板吗?
【发布时间】:2016-09-22 05:22:15
【问题描述】:

我已经学习/阅读 C++ 很长时间了,但我几乎没有写过任何东西。因此,尽管我对现代 C++ 实践了解很多,但我仍然没有很好的设计模式。

这是我的问题:假设我有一个类 Board,它代表一个游戏板(即国际象棋、围棋等)。该板的底层存储是std::array

还有一个班级GameRunner拥有一个Board,负责运行游戏规则、记分等。

游戏板的大小由用户定义。在我的脑海中,GameRunner 被简单地声明为:GameRunner::GameRunner(unsigned size),然后size 参数同样被传递到声明为:Board::Board(unsigned size) 的 Board。

问题在于std::array 的大小必须是静态确定的。所以我不能有std::array 的成员变量,因为我在编译时不知道大小是多少。我以为我可以将std::unique_ptr 作为我的成员,然后将其指向一个动态创建的数组,但是当然您需要定义std::unique_ptr<std::array<???????>>,其中问号表示我显然不知道它的大小数组。

所以我的解决方案是让 Board 有一个模板来传递大小......所以GameRunner 会有一个Board<size>,但当然 GameRunner 也需要有一个模板,所以现在都是模板往下走……

那我在这里做什么?模板一直下降?即使大小不应该改变,也要使用可变大小的容器?我觉得我错过了一些非常微不足道的东西......

【问题讨论】:

  • 你可以让板子有一个矢量大小......用无法测量的运行时速度差异换取简单的代码和更快的开发时间

标签: c++ c++11


【解决方案1】:

有人提议在 C++ 标准中添加一个针对这种情况的容器——它的大小在构建时就已确定,之后就不再更改。这被拒绝了,但如果你愿意的话,编写自己的相当容易。或者,只需使用std::vector,并接受它具有您不需要或不关心的功能的事实(但也不太可能导致问题)。

【讨论】:

【解决方案2】:

您应该使用std::vector<T> 而不是std::array<T, N>

【讨论】:

  • 我知道 std::vector 是一个解决方案。但是为了学习,我想知道是否有更好的方法来创建一个固定大小的基于堆栈的数组,其大小在运行时而不是comiletime 定义。如果没有办法,而std::vector 是唯一的办法,那我就忍了。
  • 允许使用运行时定义大小的基于堆栈的数组,但不能将它们放在对象中,因为这样对象的大小将变得可变,这会使事情变得非常复杂。例如,您将无法制作此类对象的数组。还有另外一个考虑:栈通常比堆小很多,所以最好在堆上分配大对象。因此,您不能将该数组放在堆栈上,也不能将它直接放在 Board 类中。如果它在堆上,那么 std::vector 是最自然和最简单的解决方案。
  • @AlexeyGuseynov "允许使用运行时定义大小的基于堆栈的数组" IINM,严格来说,这在 C99 中是允许的,但在 C++ 中是不允许的。 g++ 确实支持它,但它是一个不可移植的特定于编译器的语言扩展(参见 here)。
  • @andy 如果你真的希望你的数据是基于堆栈的,你可以使用 LLVM 的SmallVector 之类的东西。然后,对于相当小尺寸的板,您的数据可以在堆栈上,更大的板将被动态分配。
猜你喜欢
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 2010-10-01
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多