Restringir parámetro de plantilla de enteros

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.

preguntado el 03 de mayo de 12 a las 20:05

Just FYI, Boost.MPL already contains 100% of the logic needed for anything like this, so any code you write will simply be (possibly poor) duplication. -

2 Respuestas

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 };
};

contestado el 03 de mayo de 12 a las 20:05

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

O incluso más corto:

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

respondido 07 mar '21, 23:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.