2011-12-03 13 views
0

私はC++ 11の型記述子プロジェクトで作業しています。タイプ記述子の仕事は、クラス内のすべてのメンバーの型を知ることです。サイズはオブジェクトの基底からオフセットされています。私は仮想メソッドを持つオブジェクトだけでなく、複数の継承をサポートしていないので、今のところこれをもっと簡単にしています。目標は、記述子を使用してオブジェクトを直列化および直列化解除できるようにすることです。メンバーへのポインタ型の記述子と参照

これは可変的なテンプレート、メンバーへのポインタ、およびC++の他の機能のような機能を使いこなすペットプロジェクトです。私はよく慣れていないので、boost :: archivingのようなものを指摘する必要はありません。 :)

実際にメンバーを登録する方法は、boost :: python :: class_の方法と非常によく似ています。 https://stackoverflow.com/a/8336479/1074536ので、私は&はFooを使用することはできませんよ:::私は今週の初めに学んできたよう

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++での参照に使用することはできませんrefToAndIntなどです。

限りどのように私はメンバーのオフセットを計算していますように、私は私のクラスはいつものPODではありませんので、マクロのオフセットを使用していません。私は参照のオフセットを計算するためのポインタ・ツー・メンバーを使用することはできませんので、

だから、私は私が試してみようと思いました:

&(((Foo*)nullptr)->refToAnInt) 

をが、それは別のスタックオーバーフローのスレッドで指摘されているた、これは未定義の動作であり、明らかにLLVMではクラッシュします。 :(

私はそれが厄介になりますので、それは、サイズ、その後、何とか私の次のメンバーを揃えるために必要なパディングをComputingの追加、前のメンバーのオフセット取るようなものをやって避けるしたい

とエラーが発生しやすい

ので、 、私はそれらのトリックの両方を使用することはできませんし、offsetofははのPODのためだけである。任意の提案を、私は次の試みることができるものに、離れて私の他の恐ろしい提案から?

ありがとう!

+2

なぜ参照をシリアル化/シリアル化解除しますか?それらはコンストラクタで初期化されなければならず、とにかく後で変更することはできません。 –

+0

@ 7vies:オブジェクトを単純なバイト配列として扱うと、参照を8バイト(64ビット)のブロックとして単純に考えることができます。ここでのアイデアは、単にオブジェクトをメモリに保持するのに十分な大きさのバイト配列を割り当て、クラス記述子を使用して値をパンチすることです。私はvtableを扱っていないので、初期化のためにコンストラクタは必要ありません。明らかに、資産をロードするとシステムが永続化される前と同じ状態になるように、通常の構築中に副作用がないことを確認する必要があります。 – fronsacqc

+0

あなたは既にvtableをサポートしていないため制限があるので、私はちょうど参照をサポートしていないと言っています - これはvtableをサポートしていないという点ではマイナーな制限です。ところで、どのようにポインタや参照のシリアル化を解除するつもりですか? (明らかに、メモリの場所が異なるため、直列化中の値と同じ値に復元することはできません) –

答えて

0

を標準によると、

  1. クラス

    6 ... 自明クラスは自明なデフォルトコンストラクタ(12.1)と... を持つクラスです...

    10 A POD構造体がそのクラスであります些細なクラスと... ...両方で

12.1コンストラクタ

5 ...

A default default constructor for class X is defined as deleted if: 

... 

- any non-static data member with no brace-or-equal-initializer is of 

参照型、

... 

A default constructor is trivial if it is neither user-provided nor deleted 

及びその

... 

- for all the non-static data members of its class that are of class type(or 

が配列する場合)、そのような各クラスは、些細なデフォルトコンストラクタを有します。確かに

ブレース-OR-等しいイニシャライザは、例えば、存在しない限り、基準部材を有している任意のクラスは、PODにすることはできません。

class A 
{ 
    A &me=*this; 
}; 

この場合、あなたはできるかもしれません特定の回避策を作成します。

&(((Foo*)nullptr)->refToAnInt) 

の問題については

あなたは次のことを試すことができます。

std::aligned_storage<sizeof(Foo), std::alignment_of<Foo>::value>::type storage; 
&((static_cast<Foo *>(static_cast<void *>(&storage)))->refToAnInt); 

その行動が明確に定義されなければなりません。

+0

ええ、私は、std :: aligned_storageでバイトのスタックを割り当てることがこれを解決する唯一の方法だと考え始めています。私のAPIをちょっと汚くしなければならないので、残念です。たぶん私は参照のサポートをスキップすることもできます。 ;) – fronsacqc

関連する問題