Как обрабатывать промахи в функции get (key) C ++ HashMap?

0

Я реализовал hashmap в C++, чтобы узнать больше об ассоциативных картах в целом, и все работает хорошо, за исключением одной точки привязки - я хочу, чтобы программист мог создавать карты с произвольной параметризацией (например, [используя std::string например] HashMap<string,string*>, HashMap<string,string> и HashMap<string*,string> и т.д. являются законными).

Проблема в том, что в функции HashMap::get(int key_data) возвращаемое значение карты в пропуске (где данный ключ не соответствует каким-либо сопоставленным значениям) не может быть просто NULL если я поддерживаю наличие объектов в качестве значений карты. Я мог бы get(...) функцию get(...) всегда возвращать указатель на параметризованную карту Тип значения, но если этот тип уже является указателем, я не могу использовать унарный оператор &, и если это объект, который я должен использовать оператор &. Я определенно не хочу использовать RTTI, поэтому вопрос следующий:

Как я могу разрешать типы возвращаемых объектов и типов-указателей-объектов из моей функции HashMap::get(), которая также требуется для пропусков?

Имейте в виду, что я использую gcc 4.7 с включенным C++ 11, поэтому все функции 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()); выдает ошибку компилятора, указывающую, что оператор & требует операнда lvalue. Я могу избавиться от этой ошибки, поместив в value_data значение value_data, но это приведет к segfault, когда я действительно попытаюсь использовать его, потому что возвращенный указатель будет недействителен почти мгновенно. Просто используя ссылки на абстрактные данные, проблема синтаксиса не работает либо потому, что в этом случае пропуски не могут быть реализованы через возврат NULL (ISO требует, чтобы ссылки, в отличие от исходных указателей, указывали на допустимые значения lvalues).

Если у кого-то есть предложение относительно обработки возвращенной ссылки, которая может быть "недействительной" (например, фиктивный объект, который может быть запрошен для достоверности, что все остальное наследует), я также открыт для них.

Теги:
pointers
c++11
hashmap
reference

1 ответ

1
Лучший ответ

Одним из возможных способов решения этой проблемы будет частичная специализированная специализация. Например, как это сделать для указателей, см. Этот другой вопрос.

В принципе (скопированный из ответа там), вам понадобится

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

для предоставления специализированной версии списка для любого типа указателя.

  • 0
    хм, так что-то вроде 'template <class key_data, class value_data> class HashMap <value_data> {... обрабатывать сопоставленные объекты здесь}; " и 'template <class key_data, class value_data> class HashMap <value_data *> {... обрабатывать сопоставленные указатели здесь};'? Как компилятор будет обрабатывать ситуации, когда HashMap параметризован указателем в слоте value_data для начала (HashMap <string, string *>) - достаточно ли он умен, чтобы определить тип данных для value_data как std :: string, а затем проверить применяется ли указатель или оператор ссылки для генерации правильного кода для обработки объектов по сравнению с указателями?
  • 0
    Я поэкспериментирую с этим и скоро напишу; спасибо за предложение!
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню