0

I usually use .fill() with 1D arrays and vectors but it seems to not work with multidimensional ones. I've seen around a lot of ways to fill them, but i wonder what the most efficient is.

std::array<std::array<bool, 3>, 3> wasPlayed;
wasPlayed.fill(false);

This doesn't work, what would be the most performant way of filling wasPlayed with false values?

I played a bit and found this way:

for(int i = 0; i < 3; i++){
    wasPlayed[i].fill(false);
}

This seems to work but is it efficient?

akaManen
  • 27
  • 6
  • 2
    Thw most efficient is probably to create a class, wrapping a 1D array, and create an `operator()(y,x)` to be able to access it as a 2D array. – Ted Lyngmo May 04 '21 at 19:52
  • What do you exactly mean by "good"? – Zoso May 04 '21 at 20:20
  • @Zoso that it is as/more efficient than the answers people gave – akaManen May 04 '21 at 20:21
  • If you are worried about efficiency then probably avoid double indirection of 2-d arrays altogether and just allocate one single block and index into it for an array. Then it just boils down to setting a memory block with a value using `memset()` etc. – Zoso May 04 '21 at 20:26
  • Do you want to do it as an *initialization*, before using those objects, or in general, like "resetting" their values in a loop? – Bob__ May 05 '21 at 06:26
  • @Bob__ kinda both, i'm using it in a tictactoe program and since when a game ends it asks if you want to play another one, i need both to initialize the vectors and reset them at the start of the new matches, i decided to use the second way i wrote in the question but if you have something that might work better you're welcome to write it! – akaManen May 06 '21 at 07:42
  • No, the answers pretty much cover the "reset" part, but you can also [value initialize](https://en.cppreference.com/w/cpp/language/value_initialization) (aggregate initialization, in case of `std::array`) the object: `std::array, 3> wasPlayed {};` – Bob__ May 06 '21 at 08:20
  • @Bob__ The page on [aggregate initialization](https://en.cppreference.com/w/cpp/language/aggregate_initialization) says: "If the...initializer list is completely empty, the remaining members...are initialized by their default member initializers, if provided in the class definition, and otherwise (since C++14) copy-initialized from empty lists, in accordance with the usual list-initialization rules (which performs value-initialization for non-class types and non-aggregate classes with default constructors...." What is the value initialization of a bool? Is this specific case documented? – Justin Aug 05 '21 at 06:55
  • 1
    @Justin From the value initialization [page](https://en.cppreference.com/w/cpp/language/value_initialization), *"4) otherwise, the object is zero-initialized."*, [meaning](https://en.cppreference.com/w/cpp/language/zero_initialization) *"If T is a scalar type, the object's initial value is the integral constant zero explicitly converted to T."*. In the Standard you can find [7.3.15 **conv.bool**](https://eel.is/c++draft/conv.bool) *"A prvalue of arithmetic, ... type can be converted to a prvalue of type bool. A zero value, ... is converted to false; any other value is converted to true."*. – Bob__ Aug 05 '21 at 08:25

3 Answers3

0

As referenced from here using std::fill on a 2D int vector, Nested loop may be the best option to fill them faster (Based on comment by @juanchopanza )

vector<vector<int> > a(3,vector<int>(3));

for (int i = 0 ; i < 3; i++)
   fill(a[i].begin(),a[i].end(),falseValues);

For c++14 and above you can also use

for_each(a.begin(),a.end(),[](vector<int>& aa)
    {fill(aa.begin(),aa.end(),falseValues);});
ThivinAnandh
  • 286
  • 1
  • 8
  • wouldn't this only fill a[0][0], a[1][1], a[2][2] ? Or do indexes contain other arrays so a[0] contains a[0][0], a[0][1] and a[0][2]? – akaManen May 04 '21 at 20:07
  • No,This fills each of these of the vectors completely which are held by a[1],a[0],a[2]. So all 9 values will be filled. – ThivinAnandh May 04 '21 at 20:21
0

One way, if you want to use an array of arrays would be something like

for(auto& row: wasPlayed) {
    row.fill(true);
}
Zoso
  • 3,273
  • 1
  • 16
  • 27
0

The most efficient way to initialize an std::array of bool with false is to not do it: the default initialization for bool is false. You are done after the declaration:

std::array<std::array<bool, 3>, 3> wasPlayed;
Vlad Feinstein
  • 10,960
  • 1
  • 12
  • 27