There are many features provided in C++20, and concepts is one of them. We can use concepts to apply compile-time validation on template parameters. We can use this validation on both template classes and template functions.
Some of the important concepts are as follows:
derived_from
signed_integral
floating_point
derived_from
conceptThis concept derived_from
is used to specify whether a certain type is derived from another type or not.
The syntax of using this concept is as follows:
derived_from<Derived, Base>
derived_from
#include <concepts>class A {};class B: public A {};class C: private A{};int main() {// std::derived_from == true only for public inheritance or exact same classstatic_assert( std::derived_from<B, B> == true ); // same class: truestatic_assert( std::derived_from<int, int> == false ); // same primitive type: falsestatic_assert( std::derived_from<B, A> == true ); // public inheritance: truestatic_assert( std::derived_from<C, A> == false ); // private inheritance: false// std::is_base_of == true also for private inheritancestatic_assert( std::is_base_of_v<B, B> == true ); // same class: truestatic_assert( std::is_base_of_v<int, int> == false ); // same primitive type: falsestatic_assert( std::is_base_of_v<A, B> == true ); // public inheritance: truestatic_assert( std::is_base_of_v<A, C> == true ); // private inheritance: true}
signed_integral
conceptThis concept signed_integral
is basically used to check whether a type is signed integral or not.
The syntax of using this concept is as follows:
signed_integral<T>
In the above syntax, this concept checks whether the data type <T>
is a signed integral or not.
signed_integral
#include <concepts>#include <iostream>void print(std::signed_integral auto i) {std::cout << "Signed integral: " << i << '\n';}void print(std::unsigned_integral auto u) {std::cout << "Unsigned integral: " << u << '\n';}void print(auto x) {std::cout << "Non-integral: " << x << '\n';}int main() {print(42); // signedprint(0xFull); // unsignedprint(true); // unsignedprint('A'); // platform-dependentprint(4e-2); // non-integral (hex-float)print("∫∫∫"); // non-integral}
floating_point
conceptThis concept floating_point
is used to check whether a template type is floating-point or not.
The syntax of using this concept is as follows:
floating_point<T>
Here <T>
is a template variable, and it must be of type float
to pass this concept.
floating_point
#include <concepts>#include <iostream>#include <type_traits>using namespace std;constexpr floating_point auto x2(floating_point auto x) {return x + x;}constexpr integral auto x2(integral auto x) {return x << 1;}int main() {constexpr auto d = x2(1.1);static_assert(is_same_v<double const, decltype(d)>);cout << d << '\n';constexpr auto f = x2(2.2f);static_assert(is_same_v<float const, decltype(f)>);cout << f << '\n';constexpr auto i = x2(444);static_assert(is_same_v<int const, decltype(i)>);cout << i << '\n';}