What is the way to pass std::array<char, N>
to
such function:
template<size_t N>
void safe_func(char (&dest)[N]);
?
I try this one:
#include <array>
template <size_t N> using SafeArray = char[N];
template <size_t N> void safe_func(char (&dest)[N]) {}
int main() {
SafeArray<10> a1;
safe_func(a1);
std::array<char, 10> a2;
safe_func(*static_cast<SafeArray<10> *>(static_cast<void *>(a2.data())));
}
It works, but I doubt, may be something wrong with my cast, and on other compiler or platform (I used gcc/linux/amd64), I faced with wrong reference?
One way:
template<class T, size_t N>
using c_array = T[N];
template<class T, size_t N>
c_array<T, N>& as_c_array(std::array<T, N>& a) {
return reinterpret_cast<T(&)[N]>(*a.data());
}
int main() {
std::array<int, 2> a;
int(&b)[2] = as_c_array(a);
}
The standard requires that std::array
is an aggregate and it's only member is T[N]
, a pointer to which std::array::data()
returns. As the address of an aggregate coincides with the address of its first member, calling and dereferencing std::array::data()
is not strictly necessary, reinterpret_cast<T(&)[N]>(a)
works as well.
std::array
originated in boost, where its sole purpose was to provide a standard container interface (begin/end/size/empty/etc.
) to built-in arrays T[N]
and nothing else, so that it doesn't have any overhead, 0-cost abstraction. Hence, you can basically cast boost::array<T, N>
and T[N]
back and forth albeit possibly breaking aliasing rules by doing so (the compiler assumes that boost::array<T, N>
and T[N]
refer to different objects, so you need to know how to cope with that in your specific case).
The standard dropped all the rationale and expressed the requirements of std::array
in very weak and vague terms. So that people wonder whether it is truly only T[N]
member there and not some allegedly extra-terrestrial type that satisfies the requirement.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With