template<typename T>
inline constexpr bool is_int_v1 = std::is_same_v<T, int>;
template<typename T>
concept is_int_v2 = std::is_same_v<T, int>;
In this code block whats the difference between the inline constexpr bool
format and the concept
format.
Is one better over the other or are they equivalent?
There are many differences. Variables are variables; even if they are inline constexpr
, they are still variables. They represent objects and you can take their addresses.
A concept
is not a variable at all. You cannot take its address or do anything of the kind with it. concept
s get special grammatical rules like void func(ConceptName auto x);
that variables do not.
Variables can be templates and get to undergo template specialization. concept
s don't get to be specialized; this is deliberate. A specific concept name is associated with exactly one constraint expression no matter what template arguments are given to it.
But the most important difference is that concept
s get to follow special subsumption rules during instantiation.
When you attempt to instantiate a template that is constrained, C++ goes through a number of steps to determine which of the matching templates is the "most constrained" version that could be applied. The most constrained form is given greater weight during the resolution of which template to instantiate.
std::signed_integral<T>
is defined in terms of std::integral<T>
.
template<class T>
concept signed_integral = integral<T> && is_signed_v<T>;
This means that, if some type T
satisfies signed_integral
, then it necessarily satisfies integral
. If you have two versions of the same template, one constrained with integral
and one with signed_integral
, then passing unsigned int
will necessarily instantiate the first.
int
satisfies both concepts. But since the compiler knows that signed_integral
contains integral
, it is considered "more constrained". And therefore, that template is given priority if a type fulfills both.
That only happens if you use a concept
. If these were just inline constexpr
variables, then attempting to use int
would get a compile error since both constraints are given equal weight.
inline constexpr
variables are essentially black boxes to the constraint system. concept
s are part of the constraint system.