Reputation: 7388
How would generic accessors for a property class and their defaults be implemented?
I roughly think it would look as follows:
template<typename Type,
typename Getter = /* How to implement a default setter? */
typename Setter =
class Property {
Getter get; /* Is this right? How is it called then? */
Setter set;
Property(Type value, Getter getter, Setter setter) ...
};
Getter and Setter should be able to be given as lambdas. Is this the right approach, and how do I continue?
Upvotes: 1
Views: 1044
Reputation: 477228
You could agree to some kind of structural interface for getters and setters, and then implement something like this:
template <typename T> struct default_getter
{
T & operator()(T & x) const { return x; }
T const & operator()(T const & x) const { return x; }
};
template <typename T> struct default_setter
{
template <typename U>
void operator()(T & x, U && u) const { x = std::forward<U>(u); }
};
template <typename T,
typename Getter = default_getter<T>,
typename Setter = default_setter<T>>
class Property
{
struct PropertyImpl : Getter, Setter
{
T value;
};
PropertyImpl impl;
public:
template <typename U>
void set(U && u)
{
static_cast<Setter &>(impl)(impl.value, std::forward<U>(u));
}
T & get()
{
static_cast<Getter &>(impl)(impl.value);
}
T const & get() const
{
static_cast<Getter const &>(impl)(impl.value);
}
};
Now you can use it like so:
struct Foo
{
Property<Bar> bar;
};
Foo x;
x.bar.get();
x.bar.set(10);
Upvotes: 1
Reputation: 11502
I would propose a solution using std::function
.
template<typename T>
struct Property
{
typedef std::function<T()> GetterFunc;
typedef std::function<void(const T&)> SetterFunc;
Property (T value, GetterFunc getter, SetterFunc setter)
: m_getter(getter)
, m_setter(setter)
{
}
Property(T value)
: m_getter( [value](){ return value; }
, m_setter ( [](const T&) { } ) // I have know clue what behaviour you want here
{
}
T Get() { return m_getter(); }
void Set(const T& value) { m_setter(value); }
private:
GetterFunc m_getter;
SetterFunc m_setter;
}
Upvotes: 0