c++ - Template a python-like setattr function -
reading through previous answers, feel may have design problem, if answer academic i'd still know if possible. i've been programming in python awhile , shows. i'm trying create setattr
access on object. hand looks like:
template<class t, class u> void set_parameter_sigma(t &s, u val) { for(auto &x: s) { x.sigma = val; } } template<class t, class u> void set_parameter_epsilon(t &s, u val) { for(auto &x: s) { x.epsilon = val; } } template<class t, class u> void set_parameter_length(t &s, u val) { for(auto &x: s) { x.length = val; } }
what i'd looks following pseudocode:
template<class t, class u, class n> void set_parameter(t &s, u val) { for(auto &x: s) { x.n = val; } }
i call set_parameter(foo, 2.0, "epsilon")
, compiler create set_parameter_epsilon
function automagically. while i'm sure boost can this, i'd prefer see stl-only version if possible.
update:
oops turned out had missed requirement loop on container elements inside setter. well, then, let me amend mistake:
#include <utility> template <class c, class u, class u2 /* assignable u*/, class t = typename c::value_type> void set_parameter(c& container, u&& val, u2 (t::* pmember), typename c::value_type* sfinae=nullptr) { (auto& instance : container) (instance.*(pmember)) = std::forward<u>(val); } #include <iostream> #include <string> #include <vector> struct x { double foo; std::string splurgle; }; int main() { std::vector<x> xs(10); set_parameter(xs, 42, &x::foo); set_parameter(xs, "hello world", &x::splurgle); (auto const& x : xs) std::cout << x.foo << ", " << x.splurgle << "\n"; }
which prints (live on coliru)
42, hello world 42, hello world 42, hello world 42, hello world 42, hello world 42, hello world 42, hello world 42, hello world 42, hello world 42, hello world
original answer text:
#include <utility> #include <type_traits> template <class t, class u, class u2 /* assignable u*/, class t2 = typename std::remove_reference<t>::type> t&& set_parameter(t&& instance, u&& val, u2 (t2::* pmember)) { (instance.*(pmember)) = std::forward<u>(val); return std::forward<t>(instance); }
this littered nuances. suffice say, "works" requested:
#include <iostream> #include <string> struct x { double foo; std::string splurgle; }; int main() { x x; set_parameter(x, 3.14 , &x::foo); set_parameter(x, "hello world", &x::splurgle); std::cout << x.foo << ", " << x.splurgle; }
output:
3.14, hello world
for added insanity: note returning useful value can more ... interesting things, still:
return set_parameter( set_parameter(x(), 3.14, &x::foo), "hello world", &x::splurgle) .splurgle.length();
Comments
Post a Comment