ジェネリックラムダによるクロージャ

template structみたいな感じになります。

#include <iostream>
#include <functional>
#include <tuple>

int main() {
  const auto f = [](auto arg) {
    using type = decltype(arg);

    // member variable
    type value = arg;

    // member function
    std::function<type(void)> get;
    std::function<void(type)> set;

    // ctor
    return [=]() mutable {
      get = [&]() { return value; };
      set = [&](type arg) { value = arg; };

      return std::forward_as_tuple(get, set);
    };
  };

  auto g1 = f(0);
  std::cout << std::get<0>(g1())() << std::endl;
  std::get<1>(g1())(100);
  std::cout << std::get<0>(g1())() << std::endl;

  auto g2 = f('a');
  std::cout << std::get<0>(g2())() << std::endl;
  std::get<1>(g2())('b');
  std::cout << std::get<0>(g2())() << std::endl;
}