Standard library header<concepts> in C++ 20

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

The derived_from concept

This 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>

Example: 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 class
static_assert( std::derived_from<B, B> == true ); // same class: true
static_assert( std::derived_from<int, int> == false ); // same primitive type: false
static_assert( std::derived_from<B, A> == true ); // public inheritance: true
static_assert( std::derived_from<C, A> == false ); // private inheritance: false
// std::is_base_of == true also for private inheritance
static_assert( std::is_base_of_v<B, B> == true ); // same class: true
static_assert( std::is_base_of_v<int, int> == false ); // same primitive type: false
static_assert( std::is_base_of_v<A, B> == true ); // public inheritance: true
static_assert( std::is_base_of_v<A, C> == true ); // private inheritance: true
}

The signed_integral concept

This 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.

An example: 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); // signed
print(0xFull); // unsigned
print(true); // unsigned
print('A'); // platform-dependent
print(4e-2); // non-integral (hex-float)
print("∫∫∫"); // non-integral
}

The floating_point concept

This 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.

An example: 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';
}
Copyright ©2024 Educative, Inc. All rights reserved