2021-10-14 09:30 AM
Hi,
I need to create a struct that can be used as a Key in a hashtable.
So far I made this:
struct Item{
GS::UInt8 parentId;
GS::UInt8 itemId;
const GS::UInt8 hash = this->parentId + this->itemId;
GS::ULong Item::GenerateHashValue() {
return GS::GenerateHashValue(this->hash);
}
bool operator== (const Item& other) const {
return (this->parentId == other.parentId && this->itemId == other.itemId);
}
};
It gives me the error:
Does not have a GenerateHashValue member or non-member function. I am pretty sure I have GenerateHashValue.
Can you please point some directions on this matter?
Solved! Go to Solution.
2021-10-14 06:57 PM - edited 2021-10-14 06:57 PM
Fast tests. Works for me. VisualStudio.
Using test is:
GS::HashTable<Item,int> table;
Item itm = { 10, 20 };
table.Add(itm, 2);
table[itm] = 3;
AC24 (you need const qualifier)
GS::ULong Item::GenerateHashValue() const
{
return GS::GenerateHashValue(this->hash);
}
AC25 (dont have time to study it )
GS::ULong Item::GenerateHashValue() const
{
return GS::CalculateHashValue(this->hash);
}
And just reply. Are you shure to use summary Ids for hashe generation ?
May be beter like this:
GS::ULong Item::GenerateHashValue() const
{
return ((ULong) parentId << 8 ) | itemId;
}
2021-10-14 10:03 AM
I know how to make it work with c++ standard std::unordered_map
struct Item
{
int parentId;
short itemId;
bool operator==(const Item &other) const
{
return (parentId == other.parentId && itemId == other.itemId);
}
};
template <>
struct std::hash<Item>
{
std::size_t operator()(const Item& k) const
{
return (k.itemId + k.parentId);
}
};
with the above struct I can use the following:
Item itm = { 10, 20 };
Item itm2 = { 10, 20 };
std::unordered_map<Item, int> hashMap;
hashMap[itm] = 10;
hashMap[itm2] = 30;
std::cout << hashMap[itm2] << std::endl;
Output will be 30.
2021-10-14 12:42 PM
I think you need to mplement the GenerateHashValue as non member function.
GS::ULong GenerateHashValue( const Item& item )
{
return GS::GenerateHashValue( item.parentId + item.itemId );
}
2021-10-14 12:49 PM - last edited on 2021-10-18 02:58 AM by Laszlo Nagy
And I guess there is other variant.
Inherit your Item from GS::Hashable and implement virtual member
virtual ULong GenerateHashValue (void) const = 0;
like this
struct Item : public GS::Hashable
{
virtual ULong GenerateHashValue (void) const { return this->hash; }
}
2021-10-14 03:19 PM
It says it is already declared in the .obj file. GIS is my namespace.
Error LNK2005 "unsigned int __cdecl GIS::GenerateHashValue(struct GIS::Item const &)" (?GenerateHashValue@GIS@@YAIAEBUItem@1@@Z) already defined in AddOnMain.obj AddOn \polyGIS\Build\Source.obj
2021-10-14 03:20 PM
I can't find the GS::Hashable class.
2021-10-14 05:07 PM
Sorry. I worked on old project and checked it for old API.
It seem GS::Hashable was before AC24 and implementation of the HashTable was changed.
I will try it for API 24 and 25 later.
2021-10-14 05:11 PM
I was looking at other data structures which work with the GS::hashTable, the GS::Pair<T1, T2>. It has an implementation of the GenerateHashValue() like you said.
//This is from the GS::Pair<>
template <class Type1, class Type2>
ULong GenerateHashValue (const Pair<Type1, Type2>& pair)
{
return GS::GenerateHashValue (pair.first, pair.second);
}
2021-10-14 06:57 PM - edited 2021-10-14 06:57 PM
Fast tests. Works for me. VisualStudio.
Using test is:
GS::HashTable<Item,int> table;
Item itm = { 10, 20 };
table.Add(itm, 2);
table[itm] = 3;
AC24 (you need const qualifier)
GS::ULong Item::GenerateHashValue() const
{
return GS::GenerateHashValue(this->hash);
}
AC25 (dont have time to study it )
GS::ULong Item::GenerateHashValue() const
{
return GS::CalculateHashValue(this->hash);
}
And just reply. Are you shure to use summary Ids for hashe generation ?
May be beter like this:
GS::ULong Item::GenerateHashValue() const
{
return ((ULong) parentId << 8 ) | itemId;
}
2021-10-14 07:02 PM
I was pretty sure that there will be no conflict. Now that I think more about it will not work. Your solution works for me too, I forgot about the const, it is the same behavior as with operator overriding. Thank you very much!