Trusted answers to developer questions
Trusted Answers to Developer Questions

Related Tags

c++

How to define a concept in C++

Syed Muhammad Ali Mustafa

We use concepts to validate the template arguments through boolean predicates at compile time.

Definition types

We can define a concept in two ways:

1. Direct definition

We can define a concept directly as follows:

template < template-parameters>
concept _conceptName_ = _conceptExpression_;

Consider the example of a direct definition of a concept that validates whether or not the input arguments are of the same type.

template<typename a, typename b>
concept isSame = std::is_same<a, b>::value;

2. Using require clause

We can define a concept using require clause as follows:

template < template-parameters>
concept _conceptName_ = requires(_arguments_)
{
   _conceptExpression_;
};

Consider the example of a definition of a concept using require clause that checks whether or not two values are addable.

template<typename T>
concept Addable = requires(T num1, T num2)
{
    num1 + num2;
};
  • The concept _conceptName_ returns true if the _conceptExpression_ is true.

  • The concept _conceptName_ returns false if the _conceptExpression_ is false.

Why do we need concepts?

Suppose we want to write a sub function that subtracts two numbers. The constraint on the arguments of the function is that it should accept both int and float datatype. One option is to use the long double datatype to accept both valid datatypes.

The sub function will be as follows:

#include <iostream>

long double sub(long double num1, long double num2) 
{
    return num1-num2;
}

int main() {
  int num1{56};
  int num2{98};
  std::cout << sub(num1, num2);
}

Problem

The problem with the code snippet above is the the datatype int will be type-casted to long double. This will change the value range, as long double has greater value range than int. Also, long double requires more memory than int.

Solution

One solution to the problem stated above to use a concept, as shown below:

#include <concepts>
#include <iostream>

template <typename T>
concept Number = std::integral<T> || std::floating_point<T>;

auto sub(Number auto num1, Number auto num2) 
{
    return num1-num2;
}

int main() {
  std::cout << "sub(56, 98): " << sub(56, 98);
}

Explanation

The concept Number that is defined in line 5 checks whether the argument types are of type integer or float.

RELATED TAGS

c++

CONTRIBUTOR

Syed Muhammad Ali Mustafa
Copyright ©2022 Educative, Inc. All rights reserved
RELATED COURSES

View all Courses

Keep Exploring