Reputation: 11331
I want to be able to enforce certain rules on the "non-type" template parameters of classes. Is this possible?
For example, consider a templated "Cycle" class that cycles through values of type "TYPE", between the values "MIN" and "MAX".
A basic first step might look something like this:
template <class TYPE, TYPE MIN, TYPE MAX>
class Cycle
{
public:
Cycle() :
m_value(MIN)
{
}
const TYPE & value() const
{
return m_value;
}
void up()
{
if (m_value == m_max)
m_value = m_min;
else
++m_value;
}
void down()
{
if (m_value == m_min)
m_value = m_max;
else
--m_value;
}
private:
TYPE m_value;
static TYPE m_min;
static TYPE m_max;
};
template <class TYPE, TYPE MIN, TYPE MAX>
TYPE Cycle<TYPE, MIN, MAX>::m_min = MIN;
template <class TYPE, TYPE MIN, TYPE MAX>
TYPE Cycle<TYPE, MIN, MAX>::m_max = MAX;
How would I change the above so that the rule MIN <= MAX always holds? I.e. How do I make sure a programmer using the line
Cycle<int, 0, 23> hoursInADay;
would be allowed, but a programmer using the line
Cycle<int, 23, 0> hoursInADay;
would be warned at compile-time that the declaration in unacceptable?
Upvotes: 2
Views: 168
Reputation: 477358
You can add a static assertion:
static_assert(MIN <= MAX, "Invalid bounds");
Pre-C++11 you'll have to cook up your own construct that produces a compile-time error when invoked on a false
bool; e.g. take Boost's version of static-assert.
Otherwise something like this:
template <bool B> struct i_must_be_true; // no definition!
template <> struct i_must_be_true<true> { };
template <typename T, T MIN, T MAX> class Cycle
{
i_must_be_true<MIN <= MAX> m_check;
// ...
};
Upvotes: 6