【问题标题】:Initialize an array in C++ whose size is not fixed在 C++ 中初始化一个大小不固定的数组
【发布时间】:2014-06-25 14:40:49
【问题描述】:

我有一个 C++ 应用程序,我想在其中使用一个在其声明中初始化的数组。但是,问题在于项目的数量不是以“正常”方式固定的,而是基于枚举中的“计数器”数字:

//"Normal way"
void myMethod()
{    
    bool myArray[3] = { false, false, false };
    //...
}

//My way
//In .hpp
enum MyEnum
{
    Item1,
    Item2,
    ...,

    MyEnumCount
}

//In .cpp
void myMethod()
{    
    bool myArray[MyEnumCount] = { false, false, false };
    //...
}

开发过程中可能发生的一种情况是 MyEnum 定义发生变化,通过增加或减少其上的项目数量。这个想法是,如果发生这种情况,代码将自动适应新的枚举,而无需手动转到特定版本的部分代码。有没有办法在该数组初始化中做到这一点?或者在这种特定情况下,我必须始终在更改 MyEnum 时手动更改其初始化?

编辑: 感谢您到目前为止所写的所有回复。我正在编辑我的问题,因为我认为我上面的示例误导了一些用户为所提出的实际问题提供答案(实际上,这与我想要为我的应用程序编写的代码略有不同)。

重申我的问题:如何在其上初始化一个数组 当数组的大小为时,用他想要的值声明 由可以在代码开发期间编辑的枚举值确定 无需重新编写初始化?

这意味着:

  • 没有使用 for 循环或任何此类方法的回复是有效的,因为我正在谈论在其声明中初始化数组,而不是在代码中进一步。
  • 虽然我的初始代码将我的数组作为static 之一,但问题实际上是普遍的,也就是说,与数组是否为static 无关。因此,利用数组为static 的回复无效。当然,不是static 数组会留下一个关于为什么不使用 for 循环或类似于初始化的问题,但在这种情况下,答案应该只做一个“switch case”:“如果你有这样一个阵列,这样做的方式是休耕;如果你有另一种阵列,那么方式就是这个。
  • 代码示例附带了一个只有“false”的bool数组,但情况实际上是普遍的,即数组可能只填充“true”甚至“true”和“false”的组合排序通过某种算法,甚至可能根本不是布尔数组,而是 int 或 char 或其他任何东西。
  • 我说的是数组,而不是向量或任何 C++ 容器;)

因为我做了这个编辑,我会等到明天得到一个完整的答案,如果没有,我会用你提供的答案做一个。谢谢!

【问题讨论】:

  • [问题最初有一个static 数组。] 在这种情况下,不需要初始化器,因为默认情况下静态bools 将初始化为false
  • @RichieHindle 哇,这是个好消息 :) 但是如果它不是静态的或者我不想用“false”初始化所有这些,但有些用“false”和其他用“真的”?当然,我可以像 ikegami 建议的那样使用 for 循环,但假设我的好奇心仍然代表在声明中初始化数组(我会改变我的问题,取出那个静态来维护问题)
  • 您可能想查看std::bitset。它允许您轻松设置第 n 位。 (并且还有一个默认初始化程序)。
  • 使用std::fillstd::fill_n
  • 默认初始化是数组{},然后使用std::fillstd::beginstd::end等算法为您提供最好的安全性,尽管数组发生了变化尺寸。如果您使用std::array,您也可以使用std::array.fill()。最初的问题确实使用了static 数组,因此默认的大括号初始化将负责使数组从一开始就处于正常状态。

标签: c++ arrays enums


【解决方案1】:

指定一个空的大括号初始化列表很简单

void myMethod()
{    
    static bool myArray[MyEnumCount] = {};
    //...
}

在这种情况下,数组的所有元素都将初始化为false。由于数组是静态的,因此您甚至可以不指定初始化程序。它会被编译器自己初始化为零。

考虑到您可以使用std::array

例如

void myMethod()
{    
    static array<bool, MyEnumCount> myArray = {};
    //...
}

在这种情况下,您可以使用大括号初始化列表重新分配数组。

【讨论】:

  • OP 可能还想使用std::bitset
【解决方案2】:

那里的代码(带有MyEnumCount)可以工作,因为MyEnumCount 在编译时是不变的。

关于初始化,您可以使用一些选项;

static bool myArray[MyEnumCount] = {};

或者(如果值更复杂

static bool myArray[MyEnumCount];
// some place safe...
for (auto it = std::begin(myArray); it != std::end(myArray), ++it) {
  *it = false;
}

【讨论】:

    【解决方案3】:

    如果要将所有内容初始化为 false,请使用空列表:

    bool myArray[MyEnumCount] = {};
    

    如果您想将所有内容初始化为其他内容,请使用std::fillstd::fill_n

    bool myArray[MyEnumCount];
    std::fill_n(myArray, MyEnumCount, true);
    // or std::fill(myArray, myArray + MyEnumCount, true);
    

    【讨论】:

      【解决方案4】:

      如果不是静态的,

      bool myArray[MyEnumCount];
      for (int i=MyEnumCount; i--; )
         myArray[i] = false;
      

      【讨论】:

      • 感谢您的回答,但如上所述,这个想法不仅仅是初始化数组,而是在它的定义上进行(所以 for 循环是不可接受的)。更不用说我实际上可能不想在数组中只放“假”。
      • 根据定义,循环是必需的,无论是for 还是隐藏的(例如std::fill_n)。
      • @ikegami:你在说什么? bool myArray[MyEnumCount] = {};
      • @Lightness Races in Orbit,bool myArray[MyEnumCount] = {}; 怎么样?您是否声称不会循环?不,如果可行,它将初始化 myArray 的所有元素。
      • 这怎么是个循环?!并非所有影响超过一个字节的东西都是“循环”。
      【解决方案5】:

      可以使用没有指定足够值的初始化器,其余值将采用该类型的默认值:

      enum MyEnum
      {
          Item1,
          Item2,
          Item3,
      
          MyEnumCount
      };
      
      //In .cpp
      void myMethod()
      {    
          bool myArray[MyEnumCount] = {false, true};  // The third will be false
          //...
      }
      

      【讨论】:

      • @RichieHidle 感谢您的回答!它确实为讨论带来了一些新的东西!但是如果枚举变小了呢? :) 那么在那种情况下,额外的“假/真”会写在 myArray 的内存之外?
      • 如果初始化器中的值太多,你会得到一个编译器错误。
      【解决方案6】:

      你必须使用数组吗?或者你可以使用标准容器吗?例如,使用向量可以很容易地做到这一点:

      static std::vector<bool> myArray(false, MyEnumCount);
      

      但这是一个静态数组可能会有一些问题。您需要确保在初始化数组时已经定义了变量MyEnumCount。在您的情况下,由于静态数组位于函数内部,您只需要确保在计数定义之后调用它,这可能是。

      【讨论】:

      • 感谢您的回答,但考虑到它在我的代码中的用法,我想说没有理由去追求一个更“胖”的实现作为一个类 (std::vector) 而不是一个更简单、更少内存的用户作为一个数组。 :)
      • @Momergil 很公平 :-) 值得一提的是,std::vector 与原生数组相比,在性能方面可以非常苗条而且还不错。检查此讨论:link。在 cmets 中使用向量或此处建议的其他容器可能会帮助您更轻松地进行初始化,因此,在最坏的情况下,如果没有使用本机数组的聪明方法,请不要因为性能损失而回避使用容器。它并不像看起来那么糟糕:-)
      • 够了 :) 感谢您的回复!
      • 请记住,std::vector&lt;bool&gt; 不是 C++ 中的容器,与任何其他 std::vector&lt;T&gt; 不同。
      猜你喜欢
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-24
      相关资源
      最近更新 更多