21

標準ライブラリは 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;
}
4

2 に答える 2

18

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

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

テンプレート関数は、クラス テンプレートとして異なる型に特化しながら、部分的に型に特化することはできません。std::hash

そして、このテンプレート クラス ベースの方法では、次のような戻り値の型とキーの型にアクセスするなどのメタ プログラミングを行うことができます。

std::hash<X>::argument_type
std::hash<X>::result_type
于 2013-11-24T19:26:59.303 に答える