Member-only story

C++20 concepts: part 2

Gajendra Gulgulia
7 min readOct 30, 2021

--

In the first article about concepts, the basic rationale behind C++20’s concept was explained with the help of a very simple generic print method. Specifically the problem with pre-C++20 generic code not enforcing a requirements on the interface it should provide on the template type parameter T eventually causing a messy compilation error during substitution of T with the actual type.

In this article, I intend to dive deeper into C++20 concepts and explain more details on the idea behind concepts and usage.

Note that I’ll stick to examples with function templates for the time being and start explaining class templates in the later issues of the article after all foundations related to concepts have been explained.

1. Concepts as semantic constraint on template type

According to C++ reference page:

The intent of concepts is to model semantic categories (Number, Range, Regular Function) rather than syntactic restrictions … The ability to specify meaningful semantics is a defining characteristic of a true concept, as opposed to a syntactic constraint.

This simply means that C++ concepts model the semantic restrictions on the template parameters in terms of the interface they provide and not care how the (substituted) template parameters are used.

Lets examine this with our Printable concept from the first article more closely:

template<typename T>
concept Printable = requires(std::ostream& os, const T& msg)
{
{os << msg};
};
template <Printable T>
void print(const T& msg){
std::cout << msg;
}
template<Printable T>
void foo(T obj){ /* do something *}

The concept Printable imposes restriction on the template parameter T that it should be streamable with the std::ostream object via the operator<< , which is possible if the concrete type which substitutes T provides an overloaded operator<< in its interface. Other than that, T can be used in any other manner desired. It may not be even used with std::ostream object to stream to output. For e.g. in foo the type T is constrained with Printable concept but it might not even be used with std::ostream object in the body of foo . In other words, there…

--

--

Gajendra Gulgulia
Gajendra Gulgulia

Written by Gajendra Gulgulia

I'm a backend software developer and modern C++ junkie. I run a modern cpp youtube channel (https://www.youtube.com/@masteringmoderncppfeatures6302/videos)

Responses (1)