Вот что у меня есть:
int t[MX];
Теперь я хотел бы переписать этот код, чтобы эффективно добавить один элемент в начало этого массива без необходимости переводить все индексации на 1 в остальной части кода. Решением этой проблемы может быть что-то вроде этого:
int _t[MX+1];
int * const t = _t+1;
Проблема этого подхода в том, что теперь что-то подобное больше не работает:
memset(t, 0, sizeof t);
Проблема в том, что sizeof t
возвращает 4 вместо MX * 4, как я бы этого хотел.
Одним из возможных решений может быть:
struct
{
int a;
int b[MX];
} _t;
int (&t)[MX] = _t.b;
Но я нахожу это довольно не элегантным и неудовлетворительным.
Итак, мой вопрос будет:
Есть ли способ лучше?
Второе решение не только «не элегантное и неудовлетворительное», но и неопределенное поведение. Смотрите ответ на этот вопрос для получения дополнительной информации по теме.
Первое решение позволяет работать с отрицательными индексами, потому что ptr[index]
эквивалентно *(ptr + index)
, так что пока результат указывает на массив, у вас все будет хорошо.
Решение для sizeof
проблема может быть построена, следуя подходу, принятому дизайнерами std::array<T,size_t>
: создайте шаблонный класс, который оборачивает массив, и сделайте ваш перевод индекса внутри его оператора индекса.
Если это не работает, вы можете вернуться к комбинации ваших исходных двух решений, но без неопределенного поведения, например:
#define MX 1000
typedef int arr_mx[MX];
int _t[MX+1];
arr_mx &t = *((arr_mx*)(&_t[1]));
Других решений пока нет …