我有一个看起来像这样的模板函数:
template <class T> void foo(T* t)
{
//do stuff using:
someArray[idx]; //idx depends on T
}
有几种可能的类型T
,所以我的方法是在一个未命名的命名空间中做这样的事情:
struct Sentinel;
template <class T> struct Offsets {};
#define GENIDX(T,NUM) template <> struct Offsets<T> {static const int idx = NUM;};
GENIDX(Fox, 0)
GENIDX(Cat, 1)
GENIDX(Rat, 2)
GENIDX(Sentinel, 3)
static const size_t numTypes = Offsets<Sentinel>::idx;
然后稍后,成员数组someArray
被声明为someArray[numTypes];
并且 foo 方法是这样实现的:
template <class T> void foo(T* t)
{
typedef Offsets<T> offset_t;
someArray[offset_t::idx]; //idx depends on T
}
如果有人需要向系统添加新类型,他们只需添加一个新类型GENIDX
,一切都会正常工作。唯一的麻烦是,如果有人想要添加,比如说,Wolf
混合,但他们希望它在逻辑上出现,然后Cat
他们必须手动调整剩余的索引。我想知道是否有一种方法不需要宏中的数字索引,而是让它们自动按顺序生成。像这样的东西,除了以下不起作用:
size_t numTypes = 0;
template <class T> struct Offsets {};
#define GENIDX(T) template <> struct Offsets<T> {static const int idx = numTypes++;};
GENIDX(Fox)
GENIDX(Cat)
GENIDX(Rat)
之后numTypes
将正确包含数组的大小。当在组合中的任何地方插入新的专业时,这不需要任何索引管理,如果至少从好奇的角度来看,知道如何做到这一点会很有趣。
虽然这样做,但在我意识到我__COUNTER__
的 gcc 版本没有之后:
template <class T> struct Offsets {};
#define GENIDX(T) \
template <> struct Offsets<T> \
{ \
#include BOOST_PP_UPDATE_COUNTER() \
static const int idx = COUNTER; \
};
但上面失败了,因为我不能#include
在宏里面说......