如何使用C ++ 17功能优雅地简化(或消除)下面代码中的for loops
?
#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 }
这样的重新分配会很整洁...但它们是非法的:(
答案 0 :(得分:1)
如果您无法将scanf("%d",&minutes);
// ^
// Note no space here
更改为使用struct ethernet_frame
,那么尽管安全性较低,但仍然可以使用多个单线来复制数据。首先,使用旧的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()
使用Ranges TS,您可以不必指定要复制的数据大小:
#include <algorithm>
...
std::copy_n(std::array<unsigned char, 6>{36, 84, 23, 77, 35, 11}.begin(), std::size(eFrame.dst), eFrame.dst);
此外,如果没有一个衬里要使用多个对象,那么您当然可以总是自己编写一个函数,将问题变成一个衬里。
答案 1 :(得分: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);