A quick note: you can use C++11 templates to detect struct fields by name and type, and statically branch on them. I first heard of this solution from breeze1990 (https://gist.github.com/breeze1990/a9ba3e4e2371ff113cb1b1b5a1968d84).
Archived at: https://www.jeremykun.com/shortform/2024-06-25-1534/
Say I want to detect if a struct has a field `size` of type `int`. Create two template instantiations of the same name, here `HasStaticSize` that defaults to false.
(Code omitted for brevity. See: https://www.jeremykun.com/shortform/2024-06-25-1534/)
The latter is only resolved if `T::size` is declared as `int`, or more specifically, something that "decays" (https://en.cppreference.com/w/cpp/types/decay) to `int`. The outcome of these two is inheriting from structs whose `::value` member is constant `true` or `false`.
Then you can use `constexpr` in an `if` to branch on the check (`::value` extracts a boolean member from the templated struct), and behave differently based on the result.
(Code omitted for brevity. See: https://www.jeremykun.com/shortform/2024-06-25-1534/)
Godbolt link (https://godbolt.org/z/Wr9q7odeP), which shows the compiled code only has one branch, either returning 0 or 1 based on whether the field name resolves and the type matches.
Note removing the `decay_t` will change the result, because apparently `decay` removes `const`. You could also remove it and compare to `const int`.
This is all weird and I don't really like C++ template metaprogramming.
@j2kun D's metaprogramming is lovely and I wish other languages would have it. It was the only reason I ever tried it.
I guess I should really get into lisp one day but D had almost everything I ever wanted.