この質問は、別の質問と密接に関連しています。割り当て以外の存在しない値にアクセスするときに、どのような動作が必要ですか。言い換えれば、あなたが書くときに何をしたいですか:
std::cout << hashTable[string] << std::endl;
そしてstring
テーブルに存在しませんか?
考えられるアプローチは2つあります。エラーと見なして例外をスローするか、中止するか、または同様の方法です。または、デフォルトコンストラクターで構築された、または以前にクライアントによって提供された、ある種のデフォルトを返すことができます。
標準マップとunordered_mapは、デフォルトのコンストラクターを使用して新しい値を作成する2番目のアプローチを採用しています。これにより、非常に単純な解決策が可能になりますoperator[]
。存在しない場合は挿入し、デフォルト値で初期化します。次に、それへの参照を返します。
hashTable[string] = newString;
参照を介して既存の値に割り当てます。
多くのユースケースでは、最初のアプローチが望ましいでしょう(おそらく
contains
関数を使用するので、何かが見つかるかどうかを事前にテストできますoperator[]
)。最初のアプローチを実装するには、最初にアクセスのタイプごとに特定の機能を実装する必要があります。
template <typename Key, typename Value>
class HashTable
{
public:
Value* get( Key const& key ) const;
void set( Key const& key, Value const& value );
};
(私は一般的にこれらを公開します。クライアントによる使用を禁止する理由はありません。)
operator[]
次に、次のようにプロキシを返すように定義します。
template <typename Key, typename Value>
class HashTable
{
public:
class Proxy
{
HashTable* myOwner;
Key myKey;
public:
Proxy( HashTable* owner, Key const& key )
: myOwner( owner )
, myKey( key )
{
}
operator Value const&() const
{
Value const* result = myOwner->get( myKey );
if ( result == NULL ) {
// Desired error behavior here...
}
return *result;
}
Proxy const& operator==( Value const& value ) const
{
myOwner->set( myKey, value );
return *this;
}
};
Value* get( Key const& key ) const;
void set( Key const& key, Value const& value );
Proxy operator[]( Key const& key )
{
return Proxy( this, key );
}
};
したがって、あなたが書くとき:
hashTable[key] = newString;
、プロキシは;operator=
を呼び出します。hashTable.put( key, newString )
ただし、他のコンテキストでは、プロキシで暗黙の型変換を呼び出します。これにより、が呼び出されますhashTable.get( key )
。
場合によっては、デフォルト値を返したい場合でも、このソリューションを使用することが望ましい場合があります。get
関数はハッシュテーブルに何も挿入する必要がないため、テーブルがすべてのミスでいっぱいになることはありません。operator[]
onをオーバーロードできるconst
ので、const
ハッシュテーブルでも使用できます。また、デフォルトのコンストラクターを持つために値型を必要としません。
これには、標準で使用されているソリューションに関して1つの欠点があります。オーバーロードoperator.
できないため、プロキシを参照のように動作させることはできません。
hashTable[string].someFunction();
動作しません。回避策operator->
はプロキシでオーバーロードすることですが、これはやや不自然な構文につながります。
hashTable[string]->someFunction(); // But the hash table contains
// values, not pointers!!!
(参照への暗黙の変換によって誤解されないでください。暗黙の変換はa
式では
考慮されませんa.b
。)