std::hash が関数ではなく構造体なのはなぜですか? 質問する

std::hash が関数ではなく構造体なのはなぜですか? 質問する

標準ライブラリは、さまざまな型に特化したテンプレート構造体として std::hash を実装します。これは次のように使用されます。

#include <iostream>
#include <functional>

int main()
{
    std::hash<int> hasher;
    std::cout << hasher(1337) << std::endl;

    return 0;
}

私の質問は、この設計選択の背後にある理由は何かということです。なぜテンプレート関数として実装されず、次のように使用されないのでしょうか。

#include <iostream>
#include <functional>

int main()
{
    std::cout << std::hash<int>(1337) << std::endl;

    return 0;
}

ベストアンサー1

理由は複数ありますが、それぞれが選択するのに十分な理由です。

  1. クラス テンプレートは部分的に特殊化できますが、関数テンプレートは完全に特殊化することしかできません (少なくとも、今のところは)。したがって、std::hash<T>クラス テンプレートを使用して、関連するテンプレート引数のスイート全体を置き換えることができます。部分的なオーバーロードは役に立たないことに注意してください。ハッシュ関数は、オーバーロードされた関数では実行できないオブジェクトとして何らかの方法で指定する必要があります (オブジェクト経由でアクセスする場合は別ですが、それが差別化の対象です)。
  2. 順序付けられていない連想コンテナは静的エンティティでパラメータ化されます (特定のタイプがサポートしている場合は動的にカスタマイズすることもできます)。これはクラス テンプレートを使用すると簡単に実行できます。
  3. ハッシュ関数に使用されるエンティティはカスタマイズ可能なので、カスタマイズには型または関数ポインターのどちらかを選択します。関数ポインターはインライン化が難しい場合が多いですが、型のインライン メンバー関数はインライン化が簡単なので、単純なハッシュの計算などの単純な関数のパフォーマンスが大幅に向上します。

おすすめ記事