Replacing QVariant::Handler::canConvert

Replacing QVariant::Handler::canConvert

本文关键字:canConvert Handler Replacing QVariant      更新时间:2023-10-16

是否可以将我们自己的代码注入QVariant::canConvert?

我添加了对在我们自己的通用值容器和Qt版本(QVariant)之间转换的支持,主要基于这里的一个建议。如何支持对包含自定义类型的QVariant对象的比较?

我很确定这个问题的答案是"它不可能完成",浏览源代码显示QVariant::canConvert的实现不会调用处理程序,但出于病态的好奇心,我想我无论如何都会问。

https://github.com/qtproject/qt/blob/b05d05fd9ce2aeedfaf805a7ed9007a93c902bc9/src/corelib/kernel/qvariant.cpp#L2719

在QVariant实现中是否有任何随机的地方,我们可以在那里获得某种挂钩到这种功能中(无需重新编译Qt),如果没有,Handler上的函数是否用于任何用途/为什么它存在?大多数情况下,有什么解决这个问题的建议吗?

当然,您可以将QVariant::canConvert()与自定义数据类型一起使用。唯一需要注意的是,您必须向类型系统注册该类型。如果你不这样做,你会通过static_assert、得到一个友好的提醒

错误:静态断言失败:类型未注册,请使用Q_DECLARE_METATYPE宏,使其为Qt的元对象系统所知

例如,这个代码运行得非常好,

struct Foo {
    int a, b;
};
Q_DECLARE_METATYPE(Foo)

int main()
{
        Foo foo {1, 2};
        QVariant variant = QVariant::fromValue(foo);
        qDebug() << variant.canConvert<Foo>();
}

如果你想覆盖默认模板,你只需要提供你自己的专业化来做你想做的事,

template<>
bool QVariant::canConvert<Foo>() const {
    qDebug() << "Hello from my specialization!";
    return userType() == qMetaTypeId<Foo>();
};

没有"处理程序",因为这都是模板化的。请注意,虽然您可以专门化QVariant::value()之类的模板,但即使您专门化int情况,它也不会影响QVariant::toInt()和类似的模板。例如,

template<>
int QVariant::value<int>() const
{
    if (userType() == qMetaTypeId<Foo>()) {
        return value<Foo>().a + value<Foo>().b;
    };
    return toInt();
}
....
qDebug() << variant.value<int>() << variant.toInt();

生产,

3 0