aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/development/c++.md
diff options
context:
space:
mode:
authorJohannes Stoelp <johannes.stoelp@gmail.com>2022-09-28 22:10:29 +0200
committerJohannes Stoelp <johannes.stoelp@gmail.com>2022-09-28 22:10:29 +0200
commit99c1f88e7396ee87a812f8d114aac8d903eb7afb (patch)
tree7352e9d3e131af424be5b2a941860568c9e6db3f /src/development/c++.md
parent47218d271f20b39610d5f63b3bc7dfc86642bdba (diff)
downloadnotes-99c1f88e7396ee87a812f8d114aac8d903eb7afb.tar.gz
notes-99c1f88e7396ee87a812f8d114aac8d903eb7afb.zip
c++: pre c++20 concept example
Diffstat (limited to 'src/development/c++.md')
-rw-r--r--src/development/c++.md26
1 files changed, 26 insertions, 0 deletions
diff --git a/src/development/c++.md b/src/development/c++.md
index b42a263..1cc4003 100644
--- a/src/development/c++.md
+++ b/src/development/c++.md
@@ -32,9 +32,35 @@ available traits an operation can have:
```cpp
{{#include c++/meta2.cc:3:}}
+```
+
+## Example: Concepts pre c++20
+
+Prior to c++20's concepts, `SFINAE` and `std::void_t` can be leveraged to build
+something similar allowing to define an interface (aka trait) for a template
+parameter.
+```cpp
+{{#include c++/concepts-11.cc:3:}}
```
+The main mechanic can be explained with the following reduced example. If one
+of the `decltype(std:declval<T>...` expressions is ill-formed, the template
+specialization for `is_valid` will be removed from the candidate set due to
+[SFINAE][sfinae].
+```cpp
+template<typename T, typename = void>
+struct is_valid : std::false_type {};
+
+template<typename T>
+struct is_valid<T, std::void_t<
+ decltype(std::declval<T>().some_fun1()),
+ decltype(std::declval<T>().some_fun2())
+ >> : std::true_type {};
+```
+> `std::declval<T>()` creates an instance of type T in an unevaluated context.
+
+
[gist-strict-asliasing]: https://gist.github.com/shafik/848ae25ee209f698763cffee272a58f8
[parameter-pack]: https://en.cppreference.com/w/cpp/language/parameter_pack
[enable-if]: https://en.cppreference.com/w/cpp/types/enable_if