Created
January 18, 2022 12:35
-
-
Save jelmervdl/ed04644738b7116b3d4983d2b8037c4e to your computer and use it in GitHub Desktop.
getters and setters for nested structs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <utility> | |
| #include <iostream> | |
| template <typename Retval, typename T> | |
| auto make_ref(Retval T::*prop) { | |
| return [=](T &obj) -> Retval& { return obj.*prop; }; | |
| } | |
| template <typename Retval, typename T, typename... Args> | |
| auto make_ref(Retval T::*prop, Args... args) { | |
| auto step = make_ref(args...); | |
| return [=](T &obj) -> auto& { return step(obj.*prop); }; | |
| } | |
| template <typename Retval, typename T, typename... Args> | |
| auto make_getter(Retval T::*prop, Args... args) { | |
| auto ref = make_ref(prop, args...); | |
| return [=](T const &obj) -> auto const & { return ref(const_cast<T&>(obj)); }; | |
| } | |
| template <typename Retval, typename T, typename... Args> | |
| auto make_setter(Retval T::*prop, Args... args) { | |
| auto ref = make_ref(prop, args...); | |
| return [=](T &obj, auto val) -> void { ref(obj) = val; }; | |
| } | |
| struct Atom { | |
| int protons; | |
| }; | |
| struct Child { | |
| Atom atom; | |
| }; | |
| struct Parent { | |
| Child child; | |
| }; | |
| int main() { | |
| Parent parent{{{0}}}; | |
| auto ref = make_ref(&Parent::child, &Child::atom, &Atom::protons); | |
| auto setter = make_setter(&Parent::child, &Child::atom, &Atom::protons); | |
| auto getter = make_getter(&Parent::child, &Child::atom, &Atom::protons); | |
| int n = 0; | |
| std::cin >> n; | |
| ref(parent) = n; | |
| setter(parent, n); | |
| return getter(parent); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment