0

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

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

我很确定这个问题的答案是“它不能完成”,浏览源代码表明 QVariant::canConvert 的实现不会调用处理程序,但我想我还是会出于病态的好奇心问.

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

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

4

1 回答 1

3

当然,您可以使用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

于 2015-12-31T20:10:11.390 回答