Can I overlay std :: array on a slice? Or is there anything else I can use instead?

Is this behavior undefined?

std::array<int, 5> x = {3, 5, 1, 2, 3}; std::array<int, 3>& y = *reinterpret_cast<std::array<int, 3>*>(&x[1]); for(int i = 0; i != 3; i++) { std::cout << y[i] << "\n"; } 

Maybe yes, but I really feel that there should be a safe way to cut std::array s.

EDIT: Next sentence Radek:

 template<unsigned N, unsigned start, unsigned end, typename T> std::array<T, end - start>& array_slice(std::array<T, N>& x) { static_assert(start <= end, "start <= end"); static_assert(end <= N-1, "end <= N"); return *reinterpret_cast<std::array<T, end - start>*>(&x[start]); } 

EDIT: Well, I decided that I was unhappy with std::array and move on to something else, to any ideas?

+4
source share
2 answers

What about posting a new one?

 #include <array> #include <iostream> #include <iterator> template<typename T, std::size_t N> struct array_slice : public std::array<T,N> { ~array_slice() = delete; }; int main() { std::array<double,4> x_mu{0.,3.14,-1.,1.}; std:: cout << &x_mu << std::endl; { auto slicer = [] (std::array<double,4>& ref) { array_slice<double,3>* p = new (&ref) array_slice<double,3>; return p; }; std::array<double,3>& x_ = *slicer(x_mu); std::copy(x_.begin(),x_.end(), std::ostream_iterator<float>(std::cout," ")); std:: cout << std::endl; std:: cout << &x_ << std::endl; } std::copy(x_mu.begin(),x_mu.end(), std::ostream_iterator<float>(std::cout," ")); } 
-1
source

Yes, this behavior is undefined. You take one type and reinterpret_cast to another. Indeed, using reinterpret_cast should be a big red flag for "there are dragons here!"

As for cutting arrays, this will not happen. A std::array contains values; a slice of this will contain references to part of this array. And therefore it will not be std::array . You can copy fragments of arrays, but without using std::array . You will need to use std::vector , because it allows you to call constructors, as well as build from a range of values. Remember: std::array is just a more convenient wrapper around a C-style array.

The committee is looking at the array_ref<T> template, which is exactly what it says: a reference to some segment of an array of type T It can be a regular C-style array, std::vector , a std::array or just some memory allocated with new T[] . There are some library implementations of this class already , but so far nothing has been standardized.


The following Radek suggestion:

Hiding undefined behavior in a function does not determine its behavior. You can try to pretend that it is not undefined, but it is still there. The moment you use this reinterpret_cast , you are willing to give up life in C ++ - land.

+6
source

Source: https://habr.com/ru/post/1414446/


All Articles