#include <functional>

template <typename T>
const T& default_get(T& value)
{ return value; }

template <typename T>
const T& default_set(T& value, const T& rhs)
{ return value = rhs; }

template <typename T,
          std::function<const T& (T&)> get = default_get<T>,
          std::function<T& (T&, const T&)> set = default_set<T>>
class property
{
public:
    operator const T& () const
    { return get(_value); }

    T& operator= (const T& rhs)
    { return set(_value, rhs); }

private:
    T _value;
};

const int& log(const int& value) { std::cout << value; return value;  }

struct S
{
    property<int,
        // log() used as decorator-style logging wrapper in properties
        [] (int& value) { log(default_get<int>(value)); },
        [] (int& value, const int& rhs) { log(default_set<int>(value, rhs)); }>
            field_name;
};

/*
 * The following is already possible with plain old functions, but cumbersome to write.
 */

template <typename T,
          const T& (*get)(const T&) = default_get<T>,
          T& (*set)(T&, const T&) = default_set<T> >
class property
{
public:
    operator const T& () const
    { return get(_value); }

    T& operator= (const T& rhs)
    { return set(_value, rhs); }

private:
    T _value;
};