Reputation: 12342
I'm trying to use a non-type template parameter which type is a template instance like this:
template<size_t num> class BitValue { ... };
class Foo {
// works
template<template<size_t> class BitValue, size_t num>
bool get(BitValue<num> && t) { ... }
// fails
template<typename T> bool
template<Bitvalue<num> bit> bool get() { ... };
template<template <size_t> Bitvalue bit> bool get() { ... };
template<template <size_t> class Bitvalue bit> bool get() { ... };
template<template <size_t> BitValue, size_t num, Bitvalue<num> bit> bool get() { ... };
};
You might say: Why not use the foo.get(value)
? Foo represents a kind of bitfield that has multi-bit values and single-big values. I want foo.get<...>() for all members of the bitfield for consistency.
Why not use `foo.get<typeof(value)>'? foo.get<MultiBitType>() returns the value of the multi-bit field. foo.get<SingleBitType>() returns the raw value of the single-bit type. But unfortunately some of the bits are negated. So foo.get<NegatedValue>() should return !foo.get<typeof(NegatedValue)>().
Any ideas if it is possible to have a template non-type template parameter at all? And if so how?
Upvotes: 2
Views: 977
Reputation: 303750
It is impossible to have a non-type template parameter of type BitValue<size_t>
since the allowed types are [temp.param]:
A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
(4.1) — integral or enumeration type,
(4.2) — pointer to object or pointer to function,
(4.3) — lvalue reference to object or lvalue reference to function,
(4.4) — pointer to member,
(4.5) —std::nullptr_t
.
But you can just template on any type and delegate to a metafunction:
template <typename T>
bool get() {
size_t bit = bit_number<T>::value;
...
}
where:
template <typename T> struct bit_number;
template <size_t N>
struct bit_number<BitValue<N>> : std::integral_constant<size_t, N> { };
// other specializations
Upvotes: 2