1

I was trying to figure out how can I create sub arrays from within a larger array and got a piece of code here and started using it.

I created an array of ints

int arr[10];
for(int h=0;h<10;h++)
{
    arr[h]=20+h;
}

Now say I want a sub-array (of 4 ints) within the same larger array

int (&arrOnly4Elements)[4]=(int (&)[4])(*arr);

It works well and does what I want. While I understand references and that they point to actual objects, What I am not able to understand how the above code works. why do we need the braces to surround &arrOnly4Elements Also, can anyone explain me the RHS (int (&)[4])(*arr); in detail step by step manner.

Enlico
  • 23,259
  • 6
  • 48
  • 102
Nostalgic
  • 300
  • 1
  • 4
  • 18
  • The new standard way to do this is to use [`std::span`](https://en.cppreference.com/w/cpp/container/span) – NathanOliver May 12 '20 at 19:00
  • 2
    The code seems to violate the strict aliasing rule (which causes UB), so it doesn't really "work". – HolyBlackCat May 12 '20 at 19:01
  • @NathanOliver Thanks..Will try that out.. but i want to understand how the above works. – Nostalgic May 12 '20 at 19:01
  • @HolyBlackCat: It works seemlessly. behaves as an array of 4 ints. I keep playing with it. In case what I understood means "work" – Nostalgic May 12 '20 at 19:02
  • 1
    @RohitGaneshan [Undefined behavior](https://en.cppreference.com/w/cpp/language/ub) can have any effect, including not giving you any errors, or blowing up in your face randomly. Even if some code appears to work, it doesn't necessarily mean that it's valid. *"explain me the RHS `(int (&)[4])(*arr);` in detail"* It's a C-style cast of `*arr` to type `int (&)[4]` (which is "a reference to an array of 4 ints"). – HolyBlackCat May 12 '20 at 19:04
  • if you would work with iterators instead of the container directly (ie in this case simply pointers into the array) you would get a subarray without such contortions. – 463035818_is_not_an_ai May 12 '20 at 19:04
  • Will std:span work for primitives and structs – Nostalgic May 12 '20 at 19:10
  • @RohitGaneshan Yes it will. And if it didn't the template more than likely will reject your code at compile time. – PaulMcKenzie May 12 '20 at 19:15
  • @RohitGaneshan `std::span` will work for any array type. If you are asking if you could loop through a structs members with it, the answer is no, C++ provides no way to do that currently. – NathanOliver May 12 '20 at 19:16
  • I meant array of structs – Nostalgic May 12 '20 at 19:17

1 Answers1

1

cdecl.org translates it for you:

int (&arrrOnly4Elements)[4]: declare arrrOnly4Elements as reference to array 4 of int

int &arrrOnly4Elements[4]: declare arrrOnly4Elements as array 4 of reference to int

As NathanOliver pointed out, C++20 introduces std::span. You should take a look at it (also compare this SO question). A std::span is a templated view into an array/contiguous sequence of objects. It consists of a pointer and a size. It makes accessing arrays and sub arrays convenient (allows range based for) and safe (keeps track of the size).

int arr[10];
std::span<int> arr_span = arr;
std::span<int,4> arr_subspan1 = arr_span.first<4>();
std::span<int> arr_subspan2 = arr_span.first(4);

If you cannot yet switch to C++20 you might consider checking GSL which provides a gsl::span which was lately aligned to match std::span.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
  • @RohitGaneshan Not directly for one struct (makes no sense there), but for arrays of structs. I'll explain more in my answer. – Werner Henze May 12 '20 at 19:11
  • Yes i meant array of structs basically – Nostalgic May 12 '20 at 19:13
  • Let me provide some more details. Actually i was doing the same thing with a 2-dimensional array of structs. I set offsets for both the dimensions after creating a sub array(2-dimensional) and use those offsets while creating the next sub array. So in my question it can be *(arrr+offset). I guess all these can be handled by gsl:span. In case you would like to see exact code, i can paste after a couple of hours. Just in case I am not clear enough – Nostalgic May 12 '20 at 19:31
  • @RohitGaneshan If you have another question, feel free to post another question. If you change your question once it is answered that makes it hard to give a final answer. – Werner Henze May 12 '20 at 19:34
  • Will do. In the meantime I will try out the span – Nostalgic May 12 '20 at 19:42