2014-01-21 4 views
1

Пусть у меня есть вектор:Интерпретировать зЬй :: вектор <char> в станд :: вектор <short>

std::vector <char> c; 
c.push_back(0); 
c.push_back(1); 
c.push_back(0); 
c.push_back(1); 

Я хочу, чтобы преобразовать это в std::vector<short> s Так что элементы будут:

s[0] == 256; 
s[1] == 256; 

Потому что если вы объединить символы 0 и 1 составляет 256 в short.

Есть ли лучший способ конвертировать векторы, подобные этому?

+0

Возможно, используйте «memcpy». – herohuyongtao

+1

Опираясь на эту информацию, зависящую от реализации, часто не очень хорошая идея, особенно для переносимости. – Shoe

+0

Лучше, чем что? –

ответ

4

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

short *ptr = reinterpret_cast<short*>(c.data()); 
std::vector<short> s(ptr, ptr+c.size()/2); 

Если то, что вы хотите для обработки массива char в виде малоинтенсивного представления, равного половине числа short, независимо от конечности реализации, то это немного сложнее. Что-то вроде этого:

std::vector<short> s; 
s.reserve(c.size()/2); 
for (size_t idx = 0; idx < c.size(); idx += 2) { 
    s.push_back(c[idx] & 0xff + static_cast<unsigned>(c[idx+1]) << 8); 
} 

Помните, что это по-прежнему включает в себя переход от знака к знаковому типу, поэтому он по-прежнему зависят от реализации. Вам нужно больше бит-twiddling, чтобы сделать его действительно портативным.

+0

да, что-то вроде этого, но не совсем ... Я не уверен, что вам нужен & 0xff, и ваш << 8 будет переполняться, если вы не бросите, а также, поскольку они подписаны, не уверены, что он отлично обрабатывает отрицательные числа, поэтому я предпочитаю используя unsigned для этого, а затем просто отбросьте его, если необходимо. – CashCow

+0

@CashCow: Согласен, я просто работал над этим. И оговорка добавила об обращении от неподписанных. –

+0

Хорошо, вы редактировали. так лучше. – CashCow

1

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

Легче сделать без знака, где вы можете просто сделать что-то вроде ptr[i] + static_cast<unsigned short>(ptr[i+1]) << 8;

Если вы просто хотите, чтобы скопировать данные непосредственно литьем, это тривиально.

const short * data = reinterpret_cast< const short * > (c.data()); 
std::vector<short> s(data, data + c.size()/2); 

Он будет «обрезать» последний символ с вашего вектора, если его размер нечетный. (т. е. если вектор char имеет нечетное число символов, он будет игнорировать последний)

Примечание data является только элементом вектора в C++ 11. Для более старой версии заменить &c[0]

Смежные вопросы