【发布时间】:2013-02-04 09:30:48
【问题描述】:
我有一个接受 1 到 8 个整数参数的模板类。每个参数的允许范围是 0..15。每个参数的默认值 16 允许我检测未使用的参数。
我想将用户提供的参数数量作为编译时常量。我可以使用模板助手类和许多部分专业化来做到这一点。
我的问题是,我可以使用一些递归元编程来清理它吗?我有什么作品,但感觉在语法上可以改进。
很遗憾,我无法使用可变参数模板和任何其他 c++0x。
#include <stdint.h>
#include <iostream>
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4,uint8_t p5,uint8_t p6,uint8_t p7>
struct Counter { enum { COUNT=8 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4,uint8_t p5,uint8_t p6>
struct Counter<p0,p1,p2,p3,p4,p5,p6,16> { enum { COUNT=7 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4,uint8_t p5>
struct Counter<p0,p1,p2,p3,p4,p5,16,16> { enum { COUNT=6 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3,uint8_t p4>
struct Counter<p0,p1,p2,p3,p4,16,16,16> { enum { COUNT=5 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2,uint8_t p3>
struct Counter<p0,p1,p2,p3,16,16,16,16> { enum { COUNT=4 }; };
template<uint8_t p0,uint8_t p1,uint8_t p2>
struct Counter<p0,p1,p2,16,16,16,16,16> { enum { COUNT=3 }; };
template<uint8_t p0,uint8_t p1>
struct Counter<p0,p1,16,16,16,16,16,16> { enum { COUNT=2 }; };
template<uint8_t p0>
struct Counter<p0,16,16,16,16,16,16,16> { enum { COUNT=1 }; };
template<uint8_t p0,uint8_t p1=16,uint8_t p2=16,uint8_t p3=16,
uint8_t p4=16,uint8_t p5=16,uint8_t p6=16,uint8_t p7=16>
struct MyClass {
void printArgCount() {
std::cout << Counter<p0,p1,p2,p3,p4,p5,p6,p7>::COUNT << std::endl;
}
};
main() {
MyClass<4,7,8,12,15,1> foo;
foo.printArgCount();
}
【问题讨论】:
-
我觉得不错。我怀疑是否有更好的解决方案。
-
我不认为 Boost 的可变参数模板是获取用户想要传递的参数的选项?
-
我注意到我的解决方案和 Crog 的解决方案之间的行为差异:他计算所有非 16 参数,我数到第一个参数,即 16。目前,我认为我们可能都错了事实上,我们应该数到不是 16 的最新参数……这对你有影响吗?
-
(p1 != 16) + (p2 != 16) +...有什么问题? -
@Matthieu:不,没关系,它们都为我工作。用户在列表中的任何位置提供 16 是不合法的,因此计数到前 16 或所有非 16 都可以正常工作。
标签: c++ templates metaprogramming c++03