Есть следующий класс:
template<typename T, typename TInput = T>
requires std::convertible_to<TInput, T> && std::copyable<T>
class StylyableProperty
{
public:
using Type = T;
using InputType = TInput;
protected:
T _value;
public:
StylyableProperty() requires std::default_initializable<T>:
_value()
{}
StylyableProperty(TInput value):
_value(value)
{}
StylyableProperty(const StylyableProperty& other):
_value(other._value)
{}
StylyableProperty(StylyableProperty&& other) noexcept:
_value(std::move(other._value))
{}
virtual ~StylyableProperty() = default;
virtual void Set(TInput value)
{
_value = value;
}
virtual TInput Get() const
{
return _value;
}
operator TInput() const
{
return Get();
}
StylyableProperty& operator=(TInput value)
{
Set(value);
return *this;
}
StylyableProperty& operator=(const StylyableProperty& other)
{
_value = other._value;
return *this;
}
StylyableProperty& operator=(StylyableProperty&& other) noexcept
{
_value = std::move(other._value);
return *this;
}
const T* operator->() const { return &_value; }
};
И есть класс переопределяющий метод Set:
class WidthProperty: public StylyableProperty<float>
{
private:
UIElement& _owner;
public:
WidthProperty(UIElement& owner):
StylyableProperty<float>(0),
_owner(owner)
{}
void Set(float value) override
{
_value = value;
_owner._actualWidth = value - _owner.Margin->Right;
_owner.OnSizeChanged();
}
};
И в следующем примере:
UIElement e;
e.Width = 100; // no operator "=" matches these operands
e.Width.Set(100); // ok