Reputation: 153
is there's a way to constrain the integral template parameter as specialization instead of this code redundancy ?
// redundant code
template <int N>
struct A {};
template <>
struct A <0> {};
template <>
struct A <1> {};
// what i want is some thing like this
template <int N>
struct A {};
template <>
struct A <N < 2> {};
Upvotes: 3
Views: 719
Reputation: 45414
You could use SFINAE="Substitution Failure Is Not An Error". There are several ways this could be done here, for example
template<int N, typename E=void>
struct A { /* ... */ }; // general type
template<int N>
struct A<N, std::enable_if_t<(N<2)> >
{ /* ... */ }; // specialisation for N<2
Note that std::enable_if_t<>
is a C++14 type, it's equivalent to
template<bool C, typename T=void>
using enable_if_t = typename std::enable_if<C,T>::type;
How does it work? The definition of std::enable_if
is similar to
template<bool C, typename T=void>
struct enable_if { using type=T; };
template<typename T>
struct enable_if<false,T> {};
In particular, there is no sub-type enable_if::type
in case the condition C
is false. Thus in the above specialisation enable_if_t<(N<2)>
expands to a valid type (void
) only for N<2
. For N>=2
, we have substitution failure, since enable_if<(N<2)>::type
does not exist. C++ allows such failure, but simply ignores the resulting (invalid) code.
Upvotes: 6
Reputation: 3765
You could add a second template parameter, with a default value that selects the specialization you want:
template <int N, bool = (N < 2)>
struct A {
// code for N>=2 case
};
template <int N>
struct A<N, true> {
// code for N<2 case
};
(You don't need to name the second parameter since you'll never be referring to it explicitly.)
Upvotes: 2