C++14 でアクセッサを書いてみた
書いてみた。
[ソース]
#include <utility> #include <iostream> template<typename T, typename Member> auto setter(T t, Member member){ return [=](auto&& x){ t ->* member = x; }; } template<typename T, typename Member> auto getter(T t, Member member){ return [=]{ return t ->* member; }; } class X{ int value = 42; public: decltype(setter(std::declval<X*>(), &X::value)) set_value = setter(this, &X::value); decltype(getter(std::declval<X*>(), &X::value)) get_value = getter(this, &X::value); // auto 使いたい // auto set_value = setter(this, &X::value); // auto get_value = getter(this, &X::value); }; int main(){ X x; std::cout << x.get_value() << std::endl; x.set_value(-10); std::cout << x.get_value() << std::endl; return 0; }
[出力]
42 -10
メンバ変数に auto が使えないのでそこはだいぶ残念な事になっているけど、それ以外はすっきりと書けますね。
ちなみに C++11 だと以下のような感じ。
#include <functional> #include <iostream> template<typename T, typename Type> std::function<void(Type)> setter(T* t, Type T::* member){ return [=](Type x){ t ->* member = x; }; } template<typename T, typename Type> std::function<Type()> getter(T* t, Type T::* member){ return [=]{ return t ->* member; }; } class X{ int value = 42; public: std::function<void(int)> set_value = setter(this, &X::value); std::function<int()> get_value = getter(this, &X::value); }; int main(){ X x; std::cout << x.get_value() << std::endl; x.set_value(-10); std::cout << x.get_value() << std::endl; return 0; }
std::function を使っているので利用する側は C++14 よりもすっきりしているという。
(まぁその分オーバーヘッドが発生するけども。