12

I would like to do something like

std::array<int, 5> array1 = {{ ... }};
const std::array<int, 3>& array2 = array1[1:4]; // [x:y] doesn't exist

That is, get an array that is a sort of view of another array, without having to copy it.

2
  • 5
    In the C++ standard library, they get around this problem by passing pairs of iterators rather than a reference to an array. Random access iterators can easily be offset for a sub-range. Commented Mar 16, 2016 at 20:42
  • Except that then you are not telling the compiler the distance between the first and the last element. Without knowing you have three elements, you can't unroll the loop. Commented Mar 16, 2016 at 21:26

4 Answers 4

5

No, you can't do that. All standard library containers are unique owners of their data, and std::array is no exception. In fact, std::array is constrained to be implemented in such a way so that the elements are stored inside an actual array member of the class, which would make aliasing impossible.

There is a proposal for an array_view class that would represent a non-owning view into a contiguous block of data. You can read about it here. I don't know the status of this proposal (the current C++ standardization process confuses me).

Sign up to request clarification or add additional context in comments.

2 Comments

I thought that a reference (array&) doesn't own the data anyway.
@Slava: What about C++ Core Guidelines types span<T>, `string_span>?
5

You can if you use valarray instead of array http://en.cppreference.com/w/cpp/numeric/valarray/slice

Edit: from C++20 you can refer to a continuous sub-array with std::span

Comments

3

Yes you can, std::span in C++20 provides a view over a contiguous sequence of objects.

std::array<int, 5> array1 = {20, 10, 35, 30, 5};
std::span array2(array1.begin(), array1.begin() + 3); // {20, 10, 35}; subview of array1

The underlying data is not copied but rather referenced, therefore care should be taken to ensure the original array still exists when using the span.

Comments

-5
std::array<int, 3>& array2 = reinterpret_cast<std::array<int, 3>&>(array1);

7 Comments

Doesn't this violate strict aliasing?
@JamesRoot, it definitely does.
Violates it most violently. I can think of several off colour analogies I won't be using in a public forum.
This would rely on std::array wrapping a C-style array (in which case I am not convinced there is an aliasing violation) but the standard doesn't require that
@user4581301, I have been using this technique for a while and interestingly I never managed to make clang or gcc to produce a strict aliasing warning when using std::array. Perhaps there is something special about the internal representation of std::array<T,N> as T[N] that makes it work. I am talking about this code for example std::array<int,3> aa = {{1,2,3}}; std::array<int,2>& ee = reinterpret_cast<std::array<int,2>&>(aa[1]); assert(ee[0] == 2);
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.