2017-08-31 24 views
2

为了传输数据,我将int和float值加载到缓冲区。在通信缓冲区中混合int和float

一些例子:

void send_cmd_1(int y, int z, int a, int b) 
{ 
    int buf[5]; 
    buf[0] = 1; // command #1 
    buf[1] = y; // parameters for command #1 
    buf[2] = z; 
    buf[3] = a; 
    buf[4] = b; 
    queue_command(buf); // function to queue command 
} 

send_cmd_2(float x, int a) 
{ 
    int buf[3]; 
    buf[0] = cmd_id; 
    buf[1] = float_to_int(x); 
    buf[2] = a; 
    queue_command(buf); 
} 

我有取命令ID,以及一些数量是intfloat值的混合值的许多(60个以上)的功能。参数的数据类型由值传输到的设备决定。 我无法控制。在每个函数中,执行类似于上面的代码来打包缓冲区,然后将缓冲区排队到另一个发送数据的线程。

我正在寻找一个更优雅的方式来做到这一点,而不是创建60个函数的蛮力方法,它们都看起来像上面的轻微变化。

我发现可变模板可能是这种模式的一个很好的解决方案。

我想语法落得这样的:

send_cmd_1(int y, int z, int a, int b) 
{ 
    enqueue(1, y, z, a, b); 
} 

send_cmd_2(float x, int a) 
{ 
    enqueue(2, x, a); 
} 

其中“enqueue()”是一个可变参数函数或模板,将采取命令ID,以及intfloat值的混合,在正确的顺序,将参数打包到缓冲区并调用queue_command()函数。

我需要排队样子的帮助。

template<typename... Args> 
void enqueue(int cmd_id, Args... args) 
{ 
    int buf[sizeof...(Args)] 
    buf[0] = cmd_id; 
    for (int i = 1; i < sizeof...(Args); i++) 
    { 
     // what goes here? 
    } 
    queue_command(buf); 
} 

对于它的价值,如果“Args”是一种数据结构,它是正确的顺序,我不会真的需要对它做任何事情。只要字节顺序正确,我就可以将它排队。

queue_command(args); 

每所提出的解决方案,我结束了这一点:

void enqueue(cmd_enum cmd_id, Args... args) 
{ 
    int buf[sizeof...(Args)+1U]{static_cast<int>(cmd_id), *reinterpret_cast<int*>(&args)...}; 
    queue_command(buf); 
} 

这给了我什么,我是后。

void send_cmd_1(int y, int z, int a, int b) 
{ 
    enqueue(command_1_name, y, z, a, b); 
} 

还没有测试过。如果它不起作用,我会发布更正。

+0

非模板重载优先,因此您可以添加'void enqueue(cmd_struct const&cmd)'或'void enqueue(int cmd_id,cmd_struct const&cmd)'。 –

+1

模板版本将不具有原件的类型安全性(您可以调用enqueue(1,6。28,1723)';你应该看看你是否可以把'enqueue'变成一个'private'方法,或者至少把它放在''namespace detail''中(当你不能让编译器强制执行时''private'的约定)。 –

回答

3

不知道理解你的要求,但我想你可以写一组to_int()功能,通过实例

int to_int (int i) 
{ return i; } 

int to_int (float f) 
{ return float_to_int(f); } 

和简单的写你的可变参数enqueue()功能如下

template <typename ... Args> 
void enqueue (int cmd_id, Args ... args) 
{ 
    int buf[sizeof...(Args)+1U] { cmd_id, to_int(args)... }; 

    queue_command(buf); 
} 

观察+1尺寸为bufcmd_id需要。

+0

我们是否真的需要对每个参数进行显式转换? – AndyG

+0

@AndyG - 我不知道;如果'float_to_int()'简单地等同于'int(arg)'并且所有的'xxx_to_int()'函数都是相同的,那么我认为可以避免'to_int()'并且'buf'初始化为'int buf [sizeof ...(Args)+ 1U] {cmd_id,int(args)...};'。但只有OP知道做了什么'float_to_int()' – max66

+0

没错,我没有看到没有'float_to_int'的定义 – AndyG