C++:尝试使用等效的 STL 算法消除原始循环

C++: attempt to eliminate raw loop with equivalent STL algorithm

我正在尝试使一些 C++ 代码现代化,遵守核心准则和 post ++11 建议。我在这里提出的具体指导方针是使用 <algorithm> 工具代替原始循环,在序列中应用静态操作以生成新序列。

第一个示例说明了成功(正如我在此上下文中定义的那样)。 std::byte 的两个输入向量进来,一个出来,代表每个输入向量的成对按位异或,保持输入向量不变。这个问题的精神是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 函数的作用并不相关(如果有必要,我会包括在内),只是它需要一个兼容的十六进制字符和 returns 一个 std::byte,以及十六进制字符的数字值,即0-15,只加载4位。 问题是输入字符串有一对十六进制字符(每个半字节的值),每个都统一为一个十六进制字节。据我所知,我不能使用 std::transform,因为输入迭代器每次迭代必须跳转 2 (2 * sizeof(char)//aka container_const_iterator += 2 in this case),以提取下一个 字符在输入字符串中。

TLDR:是否有 算法ic 方法来实现以下函数 w/o 暴露的 for 循环,这不是更多 expensive/verbose 比下面的解决方案?

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;
}

如果是range-v3,那就是

std::vector<std::byte>
UnifyHexNibbles(const std::string& hexStr)
{
    if (hexStr.size() % 2)
        throw std::invalid_argument("size indivisible by 2.");


    return hexStr
        | ranges::view::chunk(2)
        | ranges::view::transform([](const auto& r)
           {
              return std::byte(CharToHexByte(r[0]) << 4 | CharToHexByte(r[1]));
           });
}

Demo

没有 <algorithm> 允许使用非专用迭代器通过非连续输入消耗进行转换。除了专门化迭代器之外,还有第三方,并且(希望)很快成为标准 alternatives/enhancements 来呈现核心 STL,例如范围(ranges repository)。请参阅用户 @Jarod42 的回答以获取范围的工作示例。