一般的な連想マップについて詳しく学ぶために、C++ でハッシュマップを実装しましたが、1 つの問題点を除いてすべてがうまく機能しstd::string
ます。などはすべて合法です)。HashMap<string,string*>
HashMap<string,string>
HashMap<string*,string>
問題は、オブジェクトをマップ値として持つことをサポートしている場合HashMap::get(int key_data)
、ミス (指定されたキーがマップされた値と一致しない) で返されたマップ値が関数内で単純にならないことです。NULL
関数が常にパラメーター化されたマップ値型へのポインターを返すようにすることもできますget(...)
が、その型が既にポインターである場合は単項演算子を使用できず&
、オブジェクトの場合は&
演算子を使用する必要があります。私は絶対に RTTI を使いたくないので、質問は次のとおりです。
関数からのオブジェクトとオブジェクトへのポインターの両方の戻り値の型を許可するにはどうすればよいHashMap::get()
ですか? これは、ミスを許可するためにも必要です。
C++11 をオンにして gcc 4.7 を使用しているため、C++11 のすべての機能と注意事項が適用されることに注意してください。以下はHashMap::get()
、「常に value_data が発生したものへのポインターを返す」パラダイムを使用して、これまでの私の関数に従います。
template <class key_data,class value_data> value_data*
HashMap<key_data,value_data>::get(key_data dk) {
int key = keyGen(dk);
int hash_val = HashFunc(key);
HashNode* entry = _table[hash_val];
while (entry != 0) {
if (entry->getCurrentKey() == key) {
//value_data val = entry->getCurrentValue(); //this temporary will be
//gone from the stack quickly and therefore the returned pointer to a
//pointer (if value_data is a pointer) will segfault
return &(entry->getCurrentValue()); //this should be legal and yield
//a pointer to a pointer (iff value_data was a pointer), but instead
//I get a compiler error claiming
//operator & requires an lvalue operand...
}
entry = entry->next();
}
printf("Your get of int key %i resulted in no hits."
"The returned pointer to Value is NULL!\n",key);
return NULL;
}
コメントが示すように、この行は、演算子に左辺値オペランドが必要であるreturn &(entry->getCurrentValue());
ことを示すコンパイラ エラーをスローします。&
スタックにテンポラリを配置することでそのエラーを取り除くことができますvalue_data
が、返されたポインタがほぼ瞬時に無効になるため、実際に使用しようとすると segfault が発生します。単純に参照を使用して構文の問題を抽象化しても機能しません。その場合、リターンを介してミスを実装できないためですNULL
(ISO では、生のポインターとは異なり、有効な左辺値を指す参照が必要です)。
「無効」である可能性のある返された参照の処理に関する提案があれば (他のすべてが継承する妥当性を照会できるダミー オブジェクトのように)、私もそれらを受け入れます。