0

独自のコードを QVariant::canConvert に挿入することは可能ですか?

カスタム タイプを含む 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 に答える