型 T と、T 型の均一な要素のみを持つ構造体があるとします。
struct Foo {
T one,
T two,
T three
};
私は以下の方法でそれらにアクセスしたいと思います:
struct Foo {
T one,
T two,
T three
T &operator [] (int i)
{
return *(T*)((size_t)this + i * cpp_offsetof(Foo, two));
}
};
cpp_offsetof
マクロ (正しいと見なされます) は次のとおりです。
#define cpp_offsetof(s, m) (((size_t)&reinterpret_cast<const volatile char&>((((s*)(char*)8)->m))) - 8)
C++ 標準はそれを保証していませんが、メンバーが固定オフセットによって離れており、上記が正しいクロスプラットフォーム ソリューションであると仮定できますか?
100% 互換性のあるソリューションは次のとおりです。
struct Foo {
T one,
T two,
T three
T &operator [] (int i) {
const size_t offsets[] = { cpp_offsetof(Foo, one), cpp_offsetof(Foo, two), cpp_offsetof(Foo, three) };
return *(T*)((size_t)this + offsets[i]);
}
};
[編集]データ メンバーへのポインターを使用して、snk_kidによって標準準拠のより高速なバージョンが提示されました[/編集]
が、私が回避しようとしている追加のルックアップ テーブルが必要です。
//EDIT
そしてもう1つ。これらのフィールドにインデックスを付けるために配列と定数だけを使用することはできません。構造体のフィールドに名前を付ける必要があります (一部のマクロではそれが必要です)。
//EDIT2
なぜそれらは構造体の名前付きフィールドでなければならないのですか? マクロとは何ですか?より大きなプロジェクトの設定システムです。単純化すると、次のようになります。
struct Foo {
int one;
int two;
}
foo;
struct Setting { void *obj, size_t filed_offset, const char *name, FieldType type }
#define SETTING(CLASS, OBJ, FIELD, TYPE) { OBJ, cpp_offsetof(CLASS, FIELD), #OBJ #FIELD, TYPE }
Setting settings[] = {
SETTING(Foo, foo, one, INT_FIELD),
SETTING(Foo, foo, two, INT_FIELD)
};
繰り返しになりますが、100% 互換性のあるソリューションではなく、99% 互換性のあるソリューションを探しています。一部のコンパイラが均一なフィールド間に不均一なパディングを配置することを期待できるかどうかを尋ねています。