我有一个带有 read() 方法的模板类。它需要根据模板参数值调用 C 函数:
read1()
、read2()
、read3()
等。有没有比打开模板值更干净的方法来做到这一点?我尝试过使用宏:
#define READ(N) read##N##()
但这不起作用,因为 X 被 C 预处理器简单地替换为“N”,导致“readN()”
int read1()
{
}
int read2()
{
}
int read3()
{
}
...
template <int N>
struct Reader
{
int read()
{
switch (N)
{
case 1:
return read1();
case 2:
return read2();
case 3:
return read3();
}
}
/* Doesn't work as X is simply replaced by the C Preprocessor as 'N' resulting in "readN()"
#define READ(X) read##X##()
int read()
{
return READ(N);
}
*/
};
一个人就可以用
if constexpr
而不是切换到正确的阅读:
constexpr
查找表,为了整洁。
如果绝望的话,
constexpr
地图的实现,但标准ISO太通用了,不能用constexpr。地图对于运行时调度更有用。
查找表作为函数指针表:
#include <iostream>
int read1(){ return 1; }
int read2(){ return 2; }
int read3(){ return 3; }
template <int N>
struct Reader
{
static constexpr int (*read_functions[])(void) = {
nullptr,
read1,
read2,
read3,
};
static_assert(N > 0 && N < std::size(read_functions));
int read() {
return read_functions[N]();
}
};
int main()
{
Reader<3> r;
std::cout << "Read " << r.read();
}
参见上帝螺栓。