IgorStack
IgorStack

Reputation: 869

Restrict integer template parameter

I've a code smth like this:

template<int N, typename T>
class XYZ {
public:
  enum { value = N };
  //...
}

Is there a way to restrict N in some way? Specifically I want to allow compilation only if N is divided by some number, let's say 6. So it turned out to be not just a type restriction. Preferred way is to do this without Boost.

Upvotes: 3

Views: 2396

Answers (2)

Szotyi
Szotyi

Reputation: 63

I leave this here for the future, since I couldn't find a good example online at the time of posting.

The C++20 way with concepts:

template<int X, int Y>
concept is_evenly_divisible = X % Y == 0;

template <int N, int M> requires is_evenly_divisible<N, M>
struct XYZ
{
    enum class something { value = N };
};

XYZ<12, 6> thing; // OK
//XYZ<11, 6> thing; // Error

Or even shorter:

template <int N, int M> requires (N % M == 0)
struct XYZ
{
    enum class something { value = N };
};

Upvotes: 2

ildjarn
ildjarn

Reputation: 62975

One C++03 approach:

template<int X, int Y>
struct is_evenly_divisible
{
    static bool const value = !(X % Y);
};

template<int N, typename T, bool EnableB = is_evenly_divisible<N, 6>::value>
struct XYZ
{
    enum { value = N };
};

template<int N, typename T>
struct XYZ<N, T, false>; // undefined, causes linker error

For C++11, you can avoid some boilerplate and give a nicer error message:

template<int N, typename T>
struct XYZ
{
    static_assert(!(N % 6), "N must be evenly divisible by 6");
    enum { value = N };
};

Upvotes: 7

Related Questions