更新:あなたの質問に対する他の回答を参照してください。各データ フレームをツリー データ モデルの独自の要素に配置する方がはるかにクリーンです。そのような要素の子は、フレーム内のデータ メンバーになります。これは、さまざまな数の要素を持つさまざまなフレームの状況に一致します。各フレームに同じ数の要素がある場合は、テーブル モデルの方が適しています。Qt のモデル ビュー システムは、すべてのデータに QVariants を使用し、任意の複雑なモデルにインデックスを付ける手段を提供します。
内部的には引き続き構造を使用してデータを保持できますが、少なくともグローバル (外部) 構造を固定する必要はありません。プロトタイプ モデルを作成するとき、各最上位要素 (たとえば、一番上の行) にそのデータ型を割り当てて、基礎となるデータ構造などを内部的に作成することができます。
元のアプローチに戻ります。
QVariant のようなアプローチが機能し、整数キーがランタイム プロパティである場合に実際に機能させる唯一の方法です。整数キーをコンパイル時にのみ有効にしたい場合は、もちろん、整数に特化したテンプレート化された関数/ファンクター/クラスメンバーがそのトリックを行います。
値がバリアントに割り当てられたので、「バリアント」は割り当てをターゲット メンバーに転送する必要があります。
theMap は、任意のコンテナ タイプにすることができます。機能は「バリアント」にあります。これは基本的に変数のハンドルであるため、Handle と呼びましょう。
変換をサポートするコーディングを行うことができます。たとえば、double ハンドルで整数の代入を許可すると便利な場合があります。
繰り返しますが、これは本当に邪悪なデザインであり、それほど壊れたものは必要ないと思います。アンチパターンです。それは叫びます:誰かが台無しにしました。やらないでください。
以下は、最も単純な実装です。
#include <QMap>
#include <QVariant>
class Handle
{
QVariant::Type type;
void * address;
public:
Handle() : type(QVariant::Invalid), address(0) {}
explicit Handle(int* p) : type(QVariant::Int), address(p) {}
explicit Handle(bool * p) : type(QVariant::Bool), address(p) {}
explicit Handle(double* p) : type(QVariant::Double), address(p) {}
Handle & operator=(int* p) { return *this = Handle(p); }
Handle & operator=(int v) {
if (type == QVariant::Int) { *(int*)address = v; }
else if (type == QVariant::Double) { *(double*)address = v; }
else Q_ASSERT(type == QVariant::Invalid);
return *this;
}
int toInt() const { Q_ASSERT(type == QVariant::Int); return *(int*)address; }
Handle & operator=(bool* b) { return *this = Handle(b); }
Handle & operator=(bool b) {
Q_ASSERT(type == QVariant::Bool); *(bool*)address = b;
return *this;
}
bool toBool() const { Q_ASSERT(type == QVariant::Bool); return *(bool*)address; }
Handle & operator=(double* p) { return *this = Handle(p); }
Handle & operator=(double d) {
Q_ASSERT(type == QVariant::Double); *(double*)address = d;
return *this;
}
int toDouble() const { Q_ASSERT(type == QVariant::Double); return *(double*)address; }
};
struct MyStruct
{
int a1;
double a2;
struct InnerStruct
{
int b1;
bool b2;
} b3;
};
int main()
{
MyStruct s;
QMap<int, Handle> map;
map[0] = &s.a1;
map[1] = &s.a2;
map[2] = &s.b3.b1;
map[3] = &s.b3.b2;
map[0] = 10;
map[1] = 1.0;
map[2] = 20;
map[3] = true;
return 0;
}