【发布时间】:2014-10-16 01:25:37
【问题描述】:
背景:我正在编写一些方法,旨在对图像中的数千个像素调用。图像可以有不同的像素格式(8 位灰度、16 位 RGB、24 位 RGB 等)。对每个像素的像素格式重新检查和分支会效率低下,因此我使用 C++ 模板在编译时为每种支持的像素格式生成整个过程的版本:
// Note: PixelFormat::Enum is an integral type.
template<PixelFormat::Enum PixelFormat>
struct EdgeTracer {
Point FindInitialEdge(const void *pixels, int stride) {
/* [...] */
}
std::vector<Point> TraceEdge(
const void *pixels, int stride, const Point &initialEdge
) {
/* [...] */
}
};
现在我想为这些方法创建包装器作为纯 C 函数(用于将 DLL 导出到 .NET P/Invoke)。目前我正在这样做:
EXPORT Point DLLAPI FindInitialEdge(
const void *pixels, int stride, PixelFormat::Enum pixelFormat
) {
switch(pixelFormat) {
case PixelFormat::Format8bppIndexed: {
return EdgeTracer<PixelFormat::Format8bppIndexed>::FindInitialEdge(
pixels, stride
);
}
case PixelFormat::Format16bppRgb565: {
return EdgeTracer<PixelFormat::Format16bppRgb565>::FindInitialEdge(
pixels, stride
);
}
case PixelFormat::Format24bppRgb888: {
return EdgeTracer<PixelFormat::Format24bppRgb888>::FindInitialEdge(
pixels, stride
);
}
default: {
// error handling
}
}
}
EXPORT PointBuffer *DLLAPI TraceEdge(
const void *pixels, int stride, const Point *initialEdge,
PixelFormat::Enum pixelFormat
) {
// Nearly the same switch statement all over again
}
当我想添加对新像素格式的支持时,必须去触摸许多不相关的功能并不是最佳选择。有没有巧妙的方法来避免多余的switch 语句?
这是我到目前为止所制作的,但我还没有设法制作它的可变版本:
template<typename T>
void invokeTemplated(
PixelFormat::Enum pixelFormat, void (T::*method)(const void *pixels)
) {
switch(pixelFormat) {
case PixelFormat::Format16bppRgb555: {
T<PixelFormat::Format16bppRgb555> instance;
((&instance)->*method)(pixels);
break;
}
// [...]
}
}
【问题讨论】:
标签: c++ templates optimization variadic-functions