Predicate and expression constraints

By , last updated July 20, 2019

Predicate constraints

Predicate constraints checks the expression if it matches a criteria.

template<typename T>
concept bool Size32 = sizeof(T) == 4;

This predicate checks if the type is 32-bits.

void test_size32(Size32 s)
{}

This test method will accept anything whose size is 4 bytes (32-bits).

A struct of 4 bytes is accepted, just as int and float.

int b = 0;

struct char4
{
    char a;
    char b;
    char c;
    char d;
} c4;

test_size32(b);     // Ok
test_size32(c4);    // Ok

A predicate constraint is evaluated in place, and it must be true for the predicate constraint to succeed. If the predicate sizeof(T) == 4 is not true, the constraint fails.

Expression constraints

Expression constraints are different than predicate constraints. Expression constraints substitute the template parameter and checks if all expressions are allowed.

If you want to check the prefix increment operator ++t, you check if that is allowed.

template<typename T>
concept bool PrefixIncrement = requires(T t)
{
    ++t;
};

With the type T = int, this expression will succeed.

Expression constraints allow for simple checking of some operations.

Professional Software Developer, doing mostly C++. Connect with Kent on Twitter.