Concepts at Compile-time

Let’s look at how different types of concepts are compiled.

We'll cover the following...

How concepts are compiled

Because we have four different ways to use concepts with functions, we might ask ourselves how they are each compiled. Can there be such a subtle reason behind allowing all these different syntaxes?

Nothing is simpler than verifying that! Let’s start first with the code and then see what goes on behind the scenes.

Press + to interact
#include <concepts>
#include <iostream>
template <typename T>
concept Number = std::integral<T> || std::floating_point<T>;
template <typename T>
//the <requires> clause
requires Number<T>
auto addRequiresClause(T a, T b) {
return a+b;
}
template <typename T>
//trailing <requires> clause
auto addTrailingRequiresClause(T a, T b) requires Number<T> {
return a+b;
}
template <Number T>
//constrained template parameter
auto addConstrainedTemplate(T a, T b) {
return a+b;
}
//abbreviated function template
auto addAbbreviatedFunctionTemplate(Number auto a, Number auto b) {
return a+b;
}
int main() {
std::cout << "addRequiresClause(1, 2): " << addRequiresClause(1, 2) << '\n';
std::cout << "addTrailingRequiresClause(1, 2): " << addTrailingRequiresClause(1, 2) << '\n';
std::cout << "addConstrainedTemplate(1, 2): " << addConstrainedTemplate(1, 2) << '\n';
std::cout << "addAbbreviatedFunctionTemplate(1, 2): " << addAbbreviatedFunctionTemplate(1, 2) << '\n';
std::cout << "addAbbreviatedFunctionTemplate(1, 2): " << addAbbreviatedFunctionTemplate(1, 2.14) << '\n';
}

Explanation

The first and third methods become the same.

template<>
int addRequiresClause<int>(int a, int b)
{
    return a +
...