Указатель на класс/структуру в качестве ключа hash_map
От: xinax Украина  
Дата: 13.04.06 07:43
Оценка:
При использовании hash_map из STLport с ключем указателем на
класс/структуру возникает ошибка при попытке вставить новый элемент:
"error C2064: term does not evaluate to a function taking 1 arguments"

Помогите пожалуйста разобраться и найти причину ошибки.


VS 7.1
STLPort 5.0


//пример кода:

#include<hash_map>


class ST {};

typedef std::hash_map< char*, char* > MapChar;   //ключ - стандартный тип
typedef std::hash_map< ST*,   char* > MapSt;     //ключ - класс


int main()
{

    MapChar mc;
    MapSt   mst;

    char* ch1 = NULL;
    char* ch2 = NULL;
    ST*   st  = new ST();

    std::pair< char*, char* > pair_mc  = std::make_pair( ch1, ch2 );
    std::pair< ST*,    char*> pair_mst = std::make_pair( st,  ch2 );


    mc.insert ( pair_mc  );    //все отлично
    mst.insert( pair_mst );    //ошибка!

    return 0;
}
Re: Указатель на класс/структуру в качестве ключа hash_map
От: Аноним  
Дата: 13.04.06 10:27
Оценка:
Здравствуйте, xinax, Вы писали:

X>При использовании hash_map из STLport с ключем указателем на

X>класс/структуру возникает ошибка при попытке вставить новый элемент:
X>"error C2064: term does not evaluate to a function taking 1 arguments"

X>VS 7.1

X>STLPort 5.0
X>...

У меня нету STLPort, поэтому буду предпологать, что в Dinkumware hash_map реализован примерно так же =). Причина в том, что нет версии stdext::hash_value для твоего типа, т.е. шаблон hash_map не знает как хэшировать по такому типу ключа. Таким образом, тебе нужно написать свою функцию примерно так, как это сделано в файле %VSINSTALLDIR%\Vc7\include\xhash:
/* 
We start off by defining a specialisation of hash_value for stdext.
This will work for stdext::hash_map<std::string, ...
If the user is using std::hash_map, we pull the specialisation into std
as well.

This comes at the top of our file before everything else to ensure we
only pull in this one specialisation.
*/

_STDEXT_BEGIN

template<class _Elem,
    class _Traits,
    class _Alloc> inline
    size_t hash_value(const _STD basic_string<_Elem, _Traits, _Alloc>& _Str)
    {    // hash string to size_t value
    typedef typename _STD basic_string<_Elem, _Traits, _Alloc>::size_type _Strsize;

    size_t _Val = _HASH_SEED;
    _Strsize _Size = _Str.size();
    if (0 < _Size)
        {    // add one or more elements
        _Strsize _Stride = (_Size / 16) + 1;
        _Size -= _Stride;    // protect against _Size near _Str.max_size()
        for(_Strsize _Idx = 0; _Idx <= _Size; _Idx += _Stride)
            _Val += (size_t)_Str[_Idx];
        }
    return (_Val);
    }

_STDEXT_END


у тебя будет что-то вроде:
namespace stdext {

inline size_t hash_value(ST const *pObj)
{    
    size_t ret = ...;
    //...
    return ret;
}

}
Re[2]: Указатель на класс/структуру в качестве ключа hash_ma
От: xinax Украина  
Дата: 14.04.06 10:51
Оценка:
Спасибо за совет, обязательно попробую так сделать. Пока что проблема немножко отошла на второй план, поскольку во время перепланировки отпала надобность в этом hash_map
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.