3

Qt のメタ タイプ システムを使用するライブラリを作成します。私のライブラリのユーザーは、QVariant にラップされるカスタム型の値を提供できます。ライブラリ内のコードの後半で、この QVariant をシリアル化する必要があります。いくつかの型のシリアライザーを実装しましたが、Qt メタ型システムで認識されているすべての型をサポートする必要はありません。JSON を使用してネットワーク経由で値を送信するために、値をシリアル化します。

しかし、私が達成したいのは、カスタムの列挙型をサポートすることです。これは、ユーザーがqtRegisterMetaType<MyEnum>("MyEnum");とにかく使用してメタ型システムに登録する必要があります。そのような列挙型を整数型に変換してシリアル化したい。

QVariant::value<int>()そのような列挙値を試してみましたが、常に 0 をQVariant::canConvert<int>()返します。false を返します。

ラップされた列挙型の整数値を取得することは可能ですか (おそらくいくつかの汚いハッキングを使用)? Qtはメタタイプシステムで列挙値をどのように処理しますか? これがここにある列挙値であると確信している場合はvoid*、生のポインターにアクセスできるかもしれません。

これは次の質問につながります: Qt メタ タイプユーザー列挙型であるかどうかを確認する方法は?

ライブラリの内部コードを書いているため、テンプレートを使用できないことに注意してください。私が持っている唯一の「もの」は QVariant であり、コンパイル時の型情報はありません。

// code in the project using my library:
MyEnum foo;
libraryFunction(foo);
// internal library code (note that compile-time type info isn't available):
QVariant foo = getValueAsVariant(...);
if (/* how to check if foo is an enum type? */)
    int enumValue = foo.value<int>(); // not working for enums!

C++ コンパイラは、列挙型の値を格納するために内部で任意の整数型 (32 ビットのものだけでなく) を使用することを選択できることを知っています。これは私にとって問題になる可能性がありますか? (たとえば、を再解釈したvoid*場合int*。ただし、void*データは QVariant 自体によって割り当てられるため、たとえば、enum の列挙型に 2 バイト以上を割り当てる可能性があることに注意してsizeof == 2ください。)

4

1 に答える 1

4

汚いハックは、QVariant を QDataStream にシリアル化し、最後の 4 バイトを int に逆シリアル化することです。これは、列挙型をチェックする方法の質問には答えません。moc の出力をさらに掘り下げて更新します。

Leemes はQMetaObject::enumerator()、クラスで定義されたすべてのメタ列挙型を提供することを発見しました。を使用して列挙型名を型 ID に変換できるため、指定された型名が列挙型かどうかを確認するにはこれで十分ですQMetaType::type()(ただし、クラス名と "::" を先頭に追加します)。列挙型を保持する QVariant から int に変換するには、単にQVariant::constData()int ポインターとして再解釈して読み取ります。できます。

于 2012-05-31T01:22:06.723 に答える