**What it teaches:** C++ Concepts are like "type requirements"
```cpp
// Define a concept
template <typename T>
concept HasName = requires(T t) {
{ t.name } -> std::convertible_to<const char*>;
};
// Use in requires clause
template <typename T>
requires HasName<T> // ✅ Concept works here!
void printName(T animal) {
std::cout << animal.name;
}
```
**Key Point:** Concepts work in `requires` clauses
..
#include <iostream>
#include <concepts>
// ==========================================
// CONCEPT: Checks if a type has certain features
// ==========================================
// Simple concept: checks if type T has a "name" member
template <typename T>
concept HasName = requires(T t) {
{ t.name } -> std::convertible_to<const char*>;
};
// Another concept: checks if type T has a "bark()" method
template <typename T>
concept CanBark = requires(T t) {
{ t.bark() } -> std::same_as<void>;
};
// ==========================================
// Types that satisfy concepts
// ==========================================
struct Dog {
const char* name = "marearts.com Rex";
void bark() { std::cout << "Woof!\n"; }
};
struct Cat {
const char* name = "marearts.com Whiskers";
// No bark() method!
};
struct Robot {
// No name field!
void bark() { std::cout << "Beep boop!\n"; }
};
// ==========================================
// Functions that use concepts in "requires"
// ==========================================
// This function ONLY accepts types that have a name
template <typename T>
requires HasName<T> // ← Concept used in requires clause
void printName(T animal) {
std::cout << "Name: " << animal.name << "\n";
}
// This function ONLY accepts types that can bark
template <typename T>
requires CanBark<T> // ← Concept used in requires clause
void makeBark(T animal) {
animal.bark();
}
// ==========================================
// Main - Try it out!
// ==========================================
int main() {
Dog dog;
Cat cat;
Robot robot;
std::cout << "=== Using Concepts in 'requires' ===\n";
// ✅ Works - Dog has name
printName(dog);
// ✅ Works - Cat has name
printName(cat);
// ❌ Won't compile - Robot doesn't have name
// printName(robot); // Uncomment to see error!
std::cout << "\n";
// ✅ Works - Dog can bark
makeBark(dog);
// ❌ Won't compile - Cat can't bark
// makeBark(cat); // Uncomment to see error!
// ✅ Works - Robot can bark
makeBark(robot);
return 0;
}
..
How to build and run?
--------------------------------------------------------------------------------------------
>g++ -std=c++20 01_concept_basics.cpp -o 01_concept_basics
>./01_concept_basics
=== Using Concepts in 'requires' ===
Name: Rex
Name: Whiskers
Woof!
Beep boop!
--------------------------------------------------------------------------------------------
What is convertible_ to and same_as??
std::same_as
And there are more predefined concepts?
These are C++20 Standard Concepts
- std::integral<T> - checks if T is an integral type
- std::floating_point<T> - checks if T is a floating point type
- std::derived_from<Derived, Base> - checks inheritance
- std::invocable<F, Args...> - checks if F can be called with Args
Thank you!
MareArts
No comments:
Post a Comment