Я пытаюсь модернизировать некоторый код C ++, придерживаясь основных рекомендаций и рекомендаций после ++ 11.Конкретное руководство, к которому я обращаюсь, - это использование <algorithm>
средств вместо сырых циклов, применяя статические операции в последовательности с целью создания новой последовательности.
Этот первый пример иллюстрирует успех (как яопределить это в этом контексте).Два входных вектора std::byte
входят, и один выходит, представляя попарно побитовое XOR каждого входного вектора, оставляя входные векторы неизмененными.Функция в духе этого вопроса: std::transform.
vector<byte> XORSmash(const vector<byte>& first, const vector<byte>& second)
{
if (first.size() != second.size())
throw std::invalid_argument("XORSMASH: input vectors were not of equal length\n");
vector<byte> convolution; convolution.reserve(first.size());
transform(first.cbegin(), first.cend(), second.cbegin(), back_inserter(convolution),
[](const byte byte1, const byte byte2) {return byte1 ^ byte2;} );
return convolution;
}
Однако есть еще одна функция, для которой у меня возникают проблемы при разработке решения без петли, которое не хуже, чем у цикла.Эта функция принимает string
HexChars (каждый символ которого в конечном итоге передает 4 бита значения) и генерирует vector<byte>
, каждый элемент которого содержит содержимое двух HexChars, один в старших 4 битах, один внизкий.То, что делает функция CharToHexByte
, точно не уместно (я включу, если это станет необходимым), просто то, что она принимает совместимый шестнадцатеричный символ и возвращает std::byte
с числовым значением шестнадцатеричного символа, то есть 0-15, загрузкатолько 4 бита.Проблема заключается в том, что во входной строке есть пары шестнадцатеричных символов (каждый из которых имеет значение), каждая из которых объединяется в один шестнадцатеричный байт.Насколько мне известно, я не могу использовать std::transform
, поскольку входные итераторы должны будут переходить на 2 (2 * sizeof(char)//aka container_const_iterator += 2 in this case
) каждой итерации, чтобы извлечь следующую пару символов во входной строке.
TLDR: существует ли алгоритм ic для реализации следующей функции без открытой петли for
, которая не является более дорогой / многословной, чем приведенное ниже решение?
vector<byte> UnifyHexNibbles(const string& hexStr)
{
if (hexStr.size() % 2)
throw std::invalid_argument("UnfyHxNbl: Input String Indivisible by 8bits. Pad if applicable.\n");
vector<byte> hexBytes; hexBytes.reserve(hexStr.size() >> 1);
//can I be eliminated elegantly?
for (size_t left(0), right(1); right < hexStr.size(); left += 2, right += 2)
hexBytes.push_back( CharToHexByte(hexStr[left]) << 4 | CharToHexByte(hexStr[right]) );
return hexBytes;
}