1

如何for loops使用 C++17 功能优雅地简化(或消除)以下代码中的代码?

#pragma pack(push, 1)
        typedef struct ethernet_frame
        {
            unsigned char   dst[6]; 
            unsigned char   src[6]; 
            unsigned short  proto;
        } ethernet_frame, *ethernet_frame_ptr;
#pragma pack(pop)

        int i;
        ethernet_frame eFrame = { {00,00,00,00,00,00}, {42, 54, 33, 67, 14, 88}, 0x800 };
        ProcessFrame(&eFrame); //A library function expecting an address of an ethernet_frame with its strict bit layout

        i = 0;
        for (unsigned char c : { 36, 84, 23, 77, 35, 11 }) eFrame.dst[i++] = c;
        ProcessFrame(&eFrame);

        i = 0;
        for (unsigned char c : { 65, 23, 74, 82, 20, 94 }) eFrame.dst[i++] = c;
        ProcessFrame(&eFrame);

        i = 0;
        for (unsigned char c : { 47, 22, 86, 45, 33, 38 }) eFrame.dst[i++] = c;
        ProcessFrame(&eFrame);

        // etc...

像这样的重新分配eFrame.Dst = { 47, 22, 86, 45, 33, 38 }会很整洁......但它们是非法的:(

4

2 回答 2

1

如果您无法更改struct ethernet_frame为 use std::array,那么您仍然可以使用几个单行代码来复制数据,尽管安全性较低。首先,使用好旧的memcpy()

#include <cstring>
...
memcpy(eFrame.dst, std::array<unsigned char, 6>{36, 84, 23, 77, 35, 11}.begin(), std::size(eFrame.dst));

或使用std::copy_n()

#include <algorithm>
...
std::copy_n(std::array<unsigned char, 6>{36, 84, 23, 77, 35, 11}.begin(), std::size(eFrame.dst), eFrame.dst);

使用Ranges TS,您可以避免指定要复制的数据的大小:

#include <experimental/ranges/algorithm>
...
std::experimental::ranges::copy(std::array<unsigned char, 6>{36, 84, 23, 77, 35, 11}, eFrame.dst);

此外,如果您想多次使用的东西没有单行,那么您当然可以自己编写一个函数,将问题变成单行。

于 2019-12-28T11:39:32.987 回答
0

不是真正的单行,而是一个使用 C++17 折叠表达式的简单函数:

template<typename... Ts, typename T>
void set_elements(T (&arr)[sizeof...(Ts)], Ts... values) {
    auto ptr = arr;
    ((*ptr++ = values), ...);
}

接着:

set_elements(eFrame.dst, 36, 84, 23, 77, 35, 11);
于 2019-12-28T12:52:39.400 回答