私は C++11 で型記述子プロジェクトに取り組んでいます。型記述子の仕事は、クラス内のすべてのメンバーの型、サイズ、およびオブジェクトのベースからのオフセットを知ることです。多重継承や仮想メソッドを持つオブジェクトはサポートしていないので、今のところこれをもっと簡単にしています。目標は、記述子を使用してオブジェクトをシリアル化および非シリアル化できるようにすることです。
これは、可変個引数テンプレート、メンバーへのポインター、および私がよく知らない C++ のその他の機能などの機能をいじるためのペット プロジェクトであるため、boost::archiving のようなものに向ける必要はありません。:)
実際にメンバーを登録する方法は、boost::python::class_ の方法とよく似ています。
ClassDescriptor fooDesc( "Foo" );
fooDesc.addMember( "a", &Foo:: a );
fooDesc.addMember( "b", &Foo:: b );
// (abridged for clarity) :
template< typename ClassType, typename MemberType >
ClassDescriptor& ClassDescriptor::addMember(
const char* name,
MemberType ClassType::* member
)
{
return addMember< MemberType >( name, reinterpret_cast< size_t >( &(((ClassType*)0)->*member)) );
}
残念ながら、今週初めに学んだように、C++ のポインターからメンバーへの機能は C++ の参照では使用できません: https://stackoverflow.com/a/8336479/1074536。たとえば、 &Foo::refToAndInt を使用します。
メンバーのオフセットを計算する方法に関しては、クラスが常に POD であるとは限らないため、マクロのオフセットを使用していません。
したがって、参照のオフセットを計算するためにメンバーへのポインターを使用できないため、次のことを試してみようと思いました。
&(((Foo*)nullptr)->refToAnInt)
しかし、別のスタック オーバーフロー スレッドで指摘されていますが、これは未定義の動作であり、明らかに LLVM ではクラッシュします。:(
前のメンバーのオフセットを取得し、そのサイズを追加してから、次のメンバーを整列させるために必要なパディングを何らかの方法で計算するようなことは避けたいと思います。
したがって、これらのトリックの両方を使用することはできず、offsetof は POD 専用です。私の他の恐ろしい提案とは別に、次に何を試すことができるかについて何か提案はありますか?
ありがとう!