Glib::Binding allows updating property from const object / via PropertyProxy_ReadOnly
The below shouldn't compile, I don't think. As source
was declared const
, and therefore we can only get a PropertyProxy_ReadOnly
from it, we should not be able to create a Binding
such that the property gets updated. But we can!
As far as I can tell, the fix would involve adding overloads like bind_property_bidirectional()
and removing that as a flag, instead specifying/disallowing it via the type system as appropriate for the const
ness of source PropertyProxy
passed. That is: bind_property()
overloads would take PropertyProxy_ReadOnly
as the source, and only bind_property_bidirectional()
would be able (or need) to take a writable PropertyProxy
.
We overload for different read/write ability of proxies, depending on if SlotTransform
s are passed, but that alone doesn't mean a given property is not modified. It also depends on the Flags
. That plus the fact that we ultimately pass PropertyProxy_Base
to bind_property_value()
means we end up with some bad const
hygiene.
#include <glibmm/binding.h>
#include <glibmm/init.h>
#include <glibmm/object.h>
#include <glibmm/property.h>
#include <type_traits>
auto
main() -> int
{
class IntHaver final: public Glib::Object {
public:
IntHaver(): Glib::ObjectBase{"IntHaver"} {}
auto property_int() const { return m_property_int.get_proxy(); }
auto property_int() { return m_property_int.get_proxy(); }
private:
Glib::Property<int> m_property_int{*this, "int"};
};
Glib::init();
auto const source = IntHaver{};
auto target = IntHaver{};
auto source_proxy = source.property_int();
static_assert( std::is_same_v< decltype(source_proxy),
Glib::PropertyProxy_ReadOnly<int> > );
// Surely this shouldnʼt compile? source is a constant instance/proxy ReadOnly
auto binding = Glib::Binding::bind_property(
source_proxy, target.property_int(), Glib::BINDING_BIDIRECTIONAL);
// Just to drive the point home: this fails. We updated the value on source.
target.property_int() = 2;
g_assert_cmpint(source.property_int(), ==, 0);
return 0;
}
The result:
Bail out! ERROR:test2.cpp:31:int main(): assertion failed (source.property_int() == 0): (2 == 0)