В одну сторону:
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);
}
Стандарт требует, чтобы std::array
был агрегатом, а его единственным членом является T[N]
, указатель, к которому возвращается std::array::data()
. Поскольку адрес агрегата совпадает с адресом его первого члена, вызов и разыменование std::array::data()
не являются строго необходимыми, reinterpret_cast<T(&)[N]>(a)
тоже работает.
std::array
появился в boost, где его единственной целью было предоставить стандартный интерфейс контейнера (begin/end/size/empty/etc.
) для встроенных массивов T[N]
и ничего больше, чтобы не было никаких накладных расходов и абстракции с нулевой стоимостью. Следовательно, вы можете в основном приводить boost::array<T, N>
и T[N]
туда и обратно, хотя, возможно, нарушая правила псевдонимов, делая это (компилятор предполагает, что boost::array<T, N>
и T[N]
относятся к разным объектам, поэтому вам нужно знать, как справиться с этим в вашем конкретном случае).
Стандарт отбросил все обоснования и выразил требования std::array
в очень слабых и расплывчатых выражениях. Так что люди задаются вопросом, действительно ли там только T[N]
член, а не какой-то якобы внеземной тип, который удовлетворяет требованию.
person
Maxim Egorushkin
schedule
19.07.2018