0

一般的な連想マップについて詳しく学ぶために、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 では、生のポインターとは異なり、有効な左辺値を指す参照が必要です)。

「無効」である可能性のある返された参照の処理に関する提案があれば (他のすべてが継承する妥当性を照会できるダミー オブジェクトのように)、私もそれらを受け入れます。

4

1 に答える 1

1

これに取り組む 1 つの可能な方法は、部分的なテンプレートの特殊化です。ポインターに対してこれを行う方法の例については、この他の質問を参照してください。

基本的に(そこの回答からコピー)、必要になります

template <class I>
class GList<I*>
{
    ...
};

任意のポインター型に特化したリストのバージョンを提供します。

于 2013-10-14T19:39:16.977 に答える