Я пытаюсь модернизировать некоторый код 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 (каждый char из которых в конечном итоге передает 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: существует ли алгоритмический способ реализовать следующую функцию без открытого цикла 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;
}