web-dev-qa-db-ja.com

C ++ 11-タイプIDの一意性

C++ 11では、私はこれを使用しています

typeid(T).name()

私自身のハッシュ計算のために。プログラムの実行またはコンパイル間で結果が同じである必要はありません。タイプごとに一意である必要があります。異なる型に対して同じ名前を返す可能性があることは知っていますが、通常はconst、ポインタなどを使用します。私の場合、Tclass XYstruct XXまたは派生型のみです。

この場合、Tは一意になると思いますか?

27
Martin Perry

std::type_index マッピングのため。

Type_indexクラスはstd :: type_infoオブジェクトのラッパークラスであり、連想コンテナおよび順序付けされていない連想コンテナのインデックスとして使用できます。 type_infoオブジェクトとの関係はポインタを介して維持されるため、type_indexはCopyConstructibleおよびCopyAssignableです。

26
StoryTeller

std::type_info::nameは実装で定義されるため、さまざまなタイプで一意であることを前提にしないでください。

ハッシュ計算のためにこれを行っているので、 std::type_info::hash_code 代わりに。これは値が一意であることを保証しない保証ですが、標準では、実装は異なる型に対して異なる値を試行して返す必要があると述べています。ハッシュマップの実装に妥当な衝突処理がある限り、これで十分です。

19
TartanLlama

cppreference で述べたように:

型の名前を含む、実装定義のnullで終了する文字列を返します。保証はありません。特に、返される文字列はいくつかのタイプで同一であり、同じプログラムの呼び出し間で変わる可能性があります。

だから、いや、できません。実際には何も想定できません。

ただし、 hash_code() は次のようになります:

size_t hash_code() const noexcept;

7戻り値:未指定の値。ただし、プログラムの1回の実行内では、等しい2つのtype_infoオブジェクトに対して同じ値を返します。

8備考:実装は、equalを比較しない2つのtype_infoオブジェクトに対して異なる値を返す必要があります。

つまり、hash_code()を使用して、2つの異なる型を区別できるのは、operator== ために type_infoはこれをサポートしています。

6

あなたができるかもしれないことは、メンバーのアドレスを取ることです。

class HashBase {
    virtual intptr_t get() = 0;
};

template <typename T>
class Hash : HashBase {
    static const int _addr = 0;
    intptr_t get() override { return reinterpret_cast<intptr_t>(&_addr); }
};
3
themagicalyang