Привести итератор к другому типу

0

Я работаю над рендерером, использующим OpenGL.

У меня есть первый класс, Geometry:

class Geometry
{
 public:

    void setIndices( const unsigned int* indices, int indicesCount );

 private:
    std::vector<unsigned char> colors;
    std::vector<float>         positions;
    std::vector<unsigned int>  indices;
};

Иногда, мои геометрии нужно запасать для своих индексов разного типа, данные могут быть:

1. std::vector<unsigned char> 
2. std::vector<short> 
3. std::vector<int>

// I've already think about std::vector<void>, but it sound dirty :/.

В настоящее время я использую unsigned int всюду, и я передаю свои данные, когда хочу установить его в мою геометрию:

const char* indices = { 0, 1, 2, 3 };
geometry.setIndices( (const unsigned int*) indices, 4 );

Позже я хотел бы обновить или прочитать этот массив во время выполнения (массив может содержать более 60000 индексов), поэтому я делаю что-то вроде этого:

std::vector<unsigned int>* indices = geometry.getIndices();
indices->resize(newIndicesCount);

std::vector<unsigned int>::iterator it = indices->begin();

Проблема в том, что мой цикл итератора на неподписанном массиве int, поэтому iterator имеет 4 байта до 4 байтов, мои исходные данные могут быть char (от 1 байт до 1 байт). Невозможно прочитать мои исходные данные или обновить его новыми данными.

Когда я хочу обновить свой вектор, мое единственное решение - создать новый массив, заполнить его данными, а затем передать его в массив unsigned int, я бы хотел повторить указатель на индексы.

  1. Как я могу сделать что-то общее (работа с unsigned int, char и short)?
  2. Как я могу перебирать массив без копирования?

Спасибо за ваше время!

Теги:
arrays
architecture
vector

1 ответ

2

Кастинг с неправильным типом указателя даст неопределенное поведение и, конечно же, потерпит неудачу, если, как здесь, тип имеет неправильный размер.

Как я могу сделать что-то общее (работа с unsigned int, char и short)?

Шаблон будет самым простым способом сделать этот общий:

template <typename InputIterator>
void setIndices(InputIterator begin, InputIterator end) {
    indices.assign(begin, end);
}

Использование (исправление вашего примера использования массива, а не указателя):

const char indices[] = { 0, 1, 2, 3 };
geometry.setIndices(std::begin(indices), std::end(indices));

Вы можете рассмотреть удобную перегрузку, чтобы напрямую принимать контейнеры, массивы и другие типы диапазонов:

template <typename Range>
void setIndices(Range const & range) {
    setIndices(std::begin(range), std::end(range));
}

const char indices[] = { 0, 1, 2, 3 };
geometry.setIndices(indices);

Как я могу перебирать массив без копирования?

Вы не можете изменить тип массива без копирования данных. Чтобы избежать копирования, вам придется ожидать правильного типа массива.

  • 0
    Спасибо! Но я не могу этого сделать, потому что мой тип становится «int», поэтому, когда я отправляю свои индексы в OpenGL, тип неправильный, поэтому примитив не рисуется. (мой unsigned char становится unsigned int): /

Ещё вопросы

Сообщество Overcoder
Наверх
Меню