[Development] Why is QVariant::data() \internal?

Jędrzej Nowacki jedrzej.nowacki at qt.io
Mon Jul 25 12:04:26 CEST 2016


On Wednesday 20 of July 2016 13:50:49 Olivier Goffart wrote:
> On Montag, 18. Juli 2016 23:15:22 CEST Konrad Rosenbaum wrote:
> > Hi,
> > 
> > On Monday 18 July 2016 07:59:21 Jędrzej Nowacki wrote:
> > > On Saturday 16 of July 2016 13:56:00 Konrad Rosenbaum wrote:
> > > > I am currently interfacing two libraries that only have QVariant in
> > > > common, most of the (value) types getting exchanged are either Qt
> > > > containers or Q_GADGETs.
> > > > 
> > > > I was relatively quick to realize that I needed the QMetaType and
> > > > QMetaObject of these objects, but it took me pretty long to find out
> > > > that I can use QVariant::data() to get at the void* that I need to
> > > > access properties and Q_INVOKABLEs.
> > > > 
> > > > Is there a particular reason that QVariant::data() is classified as
> > > > \internal or would a documentation patch be accepted?
> > > 
> > > Mostly because it should not be needed.
> > 
> > I can see why it should not be needed in 95% of situations. But there is
> > this tiny little fraction of cases in which QVariant is the only
> > commonality between interfaces. Esp. if those interfaces are supposed to
> > be generic, non-related and exchangeable.
> > 
> > I'd argue it is needed often enough to merit some documentation with a big
> > fat warning for the other 95% of cases.
> > 
> > > Why can't you use https://doc.qt.io/qt-5/qvariant.html#value or
> > > https://doc.qt.io/qt-5/qvariant.html#qvariant_cast ?
> > 
> > The library that is looking into the QVariant is a generic
> > calculation/templating engine that uses QVariant to exchange data with
> > whatever outside caller is using its services.
> > 
> > It does not know what kind of data types the calling code uses - all it
> > can
> > assume is that it gets property names to find the values it is really
> > looking for. It does not even know why it is being used.
> > 
> > The data source may be the calling code or it may be a completely
> > unrelated
> > library.
> > 
> > Example:
> > Lets assume the engine is configured to work on strings and it gets the
> > formula {'I am ' + my1.name} and "my1" is configured to be a pointer to a
> > QObject-derived class or a Q_GADGET. The formula itself will usually come
> > from some kind of configuration (otherwise: what's the point!). What the
> > library code does is parse the formula, delve into the QObject or gadget
> > behind "my1" and retrieve the property "name".
> > 
> > For some use cases demanding that structured types are QObject is simply
> > not feasible since the remainder of the use case may demand value logic
> > (in my current specific case it represents data exchanged over the
> > network).
> > 
> > Writing a formula parser is complex enough for me to definitely not
> > wanting
> > to tie it to one specific application - hence I do not want it to know the
> > specific structured types - I want it to explore those types through some
> > kind of reflection - turns out QMetaType/QMetaObject is a wonderful way of
> > doing this.
> 
> I think indeed, with the recent Q_GADGET change, there is indeed a reason to
> document QVariant::data/constData or QMetaType::IsGadget

Just small remainder why it was not public from the beginning.
	auto v1 QVariant::fromValue(gadget);
	auto v2 = v1;
At that point you do not know if v1 and v2 keeps the same gadget instance or 
just a copy of it. It may not be a problem if you call just a "getName() 
const" function because it is likely to return the same (unless "this" pointer 
is part of the name :P), but not pure method and especially something that  
alters mutable members would effect in code impossible to reason about.

I hope that would be a safer option from API perspective, Anyway I can not 
think about any alternative and it is super safe to say that QVariant::data() 
method will stay forever. 

Cheers,
 Jędrek


 



More information about the Development mailing list