#include <concepts>
#include <iostream>
//creating a concept 'Number'
template <typename T>
concept Number = std::integral<T> || std::floating_point<T>;
//using requires clause
template <typename T>
requires Number<T>
auto addRequiresClause(T a, T b) {
return a+b;
}
//using trailing requires clause
template <typename T>
auto addTrailingRequiresClause(T a, T b) requires Number<T> {
return a+b;
}
//using constrained template parameter
template <Number T>
auto addConstrainedTemplate(T a, T b) {
return a+b;
}
//using abbreviated function templates
auto addAbbreviatedFunctionTemplate(Number auto a, Number auto b) {
return a+b;
}
int main() {
std::cout << "addRequiresClause(1, 2): " << addRequiresClause(1, 2) << '\n';
// std::cout << "addRequiresClause(1, 2.5): "
// << addRequiresClause(1, 2.5) << '\n';
// error: no matching function for call to 'addRequiresClause(int, double)'
std::cout << "addTrailingRequiresClause(1, 2): "
<< addTrailingRequiresClause(1, 2) << '\n';
// std::cout << "addTrailinRequiresClause(1, 2): "
// << addTrailinRequiresClause(1, 2.5) << '\n';
// error: no matching function for call to
// 'addTrailinRequiresClause(int, double)'
std::cout << "addConstrainedTemplate(1, 2): "
<< addConstrainedTemplate(1, 2) << '\n';
// std::cout << "addConstrainedTemplate(1, 2): "
// << addConstrainedTemplate(1, 2.5) << '\n';
// error: no matching function for call to 'addConstrainedTemplate(int, double)'
std::cout << "addAbbreviatedFunctionTemplate(1, 2): "
<< addAbbreviatedFunctionTemplate(1, 2) << '\n';
std::cout << "addAbbreviatedFunctionTemplate(1, 2): "
<< addAbbreviatedFunctionTemplate(1, 2.14) << '\n';
}