6

次のコードが一意の typeID であることが保証されているのはなぜですか?!

using TypeId = uintptr_t; 

template < typename T >
static TypeId GetTypeId()
{
   static uint32_t placeHolder;
   return (reinterpret_cast<TypeId>(&placeHolder));
} 

ソース

これが一種の「誤用」としての単なるランダムなメモリ位置ではない理由がわかりません...事前に回答をありがとう。

4

1 に答える 1

8

序章

実装がブロックスコープの静的変数の「ランダムなメモリ位置」を悪用することは正しいですが、それはあなたが話している保証が保持されないという意味ではありません:返される fromは、そのインスタンス化ごとに一意になります.GetTypeId<T>

: ただし、すべてのプラットフォームで使用できることが保証されているわけuintptr_tではないことに注意してください。関数を実装する完全に移植可能な方法は、プログラム内のすべてのオブジェクトのすべてのアドレスを保持できることが保証されているを返すことです。void*


個別アドレス保証...

C++ では、別のサブオブジェクトであるオブジェクトについて話している場合を除き、すべてのオブジェクトが一意のアドレスに存在する必要があるという保証があります。そのような場合、それらは同じアドレスを持つことができます (また、標準レイアウト クラスとそれらの最初のデータ メンバーのように、アドレスの共有が必要な場合)。

1.8p6 C++ オブジェクト モデル [intro.object]

オブジェクトがビットフィールドまたはサイズがゼロの基本クラスのサブオブジェクトでない限り、そのオブジェクトのアドレスは、それが占有する最初のバイトのアドレスです。ビット フィールドではない 2 つのオブジェクトは、一方が他方のサブオブジェクトである場合、または少なくとも 1 つがサイズ 0 の基底クラス サブオブジェクトであり、それらが異なる型である場合、同じアドレスを持つ可能性があります。それ以外の場合、それらは別個のアドレスを持つものとします


関数内の静的変数...

また、静的変数を含む関数テンプレートのすべての特殊化には、静的変数の独自のコピーがあることを示す明示的な句もあります。

14.8p2 関数テンプレートの特殊化 [temp.fct.spec]

テンプレートからインスタンス化された各関数テンプレートの特殊化には、静的変数の独自のコピーがあります。

staticと宣言された変数はのすべてのインスタンス化に対して一意であるためGetTypeId<T>Tは任意の型であるためplaceHolder、このテンプレートの特殊化で指定されたすべてのオブジェクトは一意のオブジェクトでなければなりません。

それは一意のオブジェクトでなければなりません。個別のアドレスが必要です。


注1)C++ 11では、あなたが求めてstd::type_indexいる保証を満たすものがあります。
注 2)この投稿では、 C++11標準ドラフトn3337を参照として使用しています。

于 2014-06-16T21:40:29.397 に答える