将定义的函数片段更改为可测试函数,如何传递参数?

Tha*_*lia 3 c++ macros c-preprocessor

我试图重构一些代码,使其可测试.其中很大一部分使用#define来填充函数中的重复代码.我试图在实际功能中改变它,但我遇到了绊脚石.

注意:原始代码来自抖动算法

typedef struct{
    unsigned char R, G, B;
} RGBTriple;

#define compute_disperse(channel) \
error = ((int)(currentPixel->channel)) - palette.table[index].channel; \
image.pixels[(x+1) + (y+0)*image.width].channel += (error*7) >> 4; \
image.pixels[(x-1) + (y+1)*image.width].channel += (error*3) >> 4; \
image.pixels[(x+0) + (y+1)*image.width].channel += (error*5) >> 4; \
image.pixels[(x+1) + (y+1)*image.width].channel += (error*1) >> 4;
Run Code Online (Sandbox Code Playgroud)

在实际方法里面

RGBTriple* currentPixel = &(image.pixels[x + y*image.width]);
compute_disperse(R);
compute_disperse(G);
compute_disperse(B);
Run Code Online (Sandbox Code Playgroud)

如果我尝试将compute_disperse转换为实际函数,那么我需要以某种方式将"channel"作为R,G或B的值传递.

我试图将它作为unsigned char传递但我收到错误

error: 'struct RGBTriple' has no member named 'channel'
Run Code Online (Sandbox Code Playgroud)

我读到了定义RG和B,但无法使其工作......如何将给定的部分转换为实际的函数,而不是宏?

Que*_*tin 7

作为Slava答案的后续内容,您可以使用成员指针...作为模板参数!

template <unsigned char RGBTriple::*Tchannel>
compute_disperse(/* Whatever you need */) {
    error = ((int)(currentPixel->*Tchannel)) - palette.table[index].*Tchannel;
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

任何体面的编译器都可以进行最少的输入,灵活,完全内联.