Have some template classes defined as follows:
template <typename T>
class Data {
[...]
};
In some other classes, I need to both use a type and a corresponding integer ID, as defined by the Python numpy C API.
E.g. the numpy API defines types such as npy_bool
which correspond to constants such as NPY_BOOL
, for all base types.
The issue is that even though values NPY_BOOL
, NPY_INT
etc are all different, the corresponding types are not. npy_bool
and npy_uint8
are both aliases of unsigned char
, but are interpreted differently by the numpy down the road.
I want to derive some template classes working on different types where the corresponding ID is also available to the class methods.
I tried to use trait classes mapping types to IDs, e.g.
template <typename T> struct Type { static const int Id = 0; };
template <> struct Type<npy_bool> { static const int Id = NPY_BOOL; };
template <> struct Type<npy_uint8> { static const int Id = NPY_UINT8; };
[...]
but the complier rejects these template definitions as the types npy_bool
and npy_uint8
are actually both unsigned char
.
I then tried the opposing traits mapping an integer ID to a corresponding base type:
template <int ID> struct Type { typedef int C; };
template <> struct Type<NPY_BOOL> { typedef npy_bool C; };
template <> struct Type<NPY_UINT8> { typedef npy_uint8 C; };
[...]
The templates describing the reverse mapping are now accepted by the compiler, but when I try to use them in further template definitions, such as:
template <int ID>
class DataPython: public Data<Type<ID>::C> {
[...]
};
this is rejected flatly by the compiler. g++ complains that it "expected a type, got Type<ID>::C
".
I can imagine solutions such as
- providing the type IDs separately, with some runtime verification that the numerical ID and the base type are compatible.
- encapsulating the base types the compiler considers to be identical in different classes in order differentiate them, at the expense of losing the underlying semantics (operators, etc.).
but neither looks very elegant. Surely there must be a better way.