Skip to content

Instantly share code, notes, and snippets.

@jelmervdl
Created January 18, 2022 12:35
Show Gist options
  • Save jelmervdl/ed04644738b7116b3d4983d2b8037c4e to your computer and use it in GitHub Desktop.
Save jelmervdl/ed04644738b7116b3d4983d2b8037c4e to your computer and use it in GitHub Desktop.
getters and setters for nested structs
#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