# Parameterized constraints

By , last updated November 14, 2019

There are two kinds of parameterized constraints, one to check if an expression between two operands are allowed, and one for checking a constant value. It’s not legal to put a constraint on non-constant values.

``````template<typename T>
concept bool ParameterizedConstraint = requires (T a, T b)
{
a == b;
a != b;
};``````

The concept `ParameterizedConstraint` checks if both operations `a == b` and `a != b` are defined and allowed. It does not check the values of `a` and `b`.

The following example contains one subtle mistake. Hint: It will build for any type of `T`.

``````template<typename T>
concept bool ParameterizedConstraint2 = requires (T a, T b)
{
sizeof(a) == 4;
a == b;
a != b;
};``````

The subtle mistake is `sizeof(a) == 4;`. The requirement for a parameterized expression is that both operands are constant. Both `sizeof(a)` and `4` are constants. What actually is checked is if the equals operator `==` is defined between two integer types. It does not check if the size of `a` is 4 bytes!

``````template<typename T>
concept bool ParameterizedConstraint3 = requires (T a, T b)
{
requires sizeof(a) == 4;
a == b;
a != b;
};``````

To check constant values in a requires section, the `requires` keyword is required. To check for the size, add `requires` in front of the expression, `requires sizeof(a) == 4;`.

What is the difference between the following two concepts?

``````template<typename T>
concept bool ParameterizedConstraint4 =
requires
{
4 == 5;
};``````
``````template<typename T>
concept bool ParameterizedConstraint5 =
requires
{
requires 4 == 5;
};`````` 