On 2011-12-01 14:05:07 +0000, Daniel James said:
On 1 December 2011 07:48, Kelvin Chung <kelvSYC@mac.com> wrote:
I'm having a hard time reconciling two distinct notions. Suppose I have a class hierarchy with root class Foo, and subclasses Foo1, Foo2, etc. (all of which are leaf classes) Now, suppose that hash_value() is defined for all the subclasses but not Foo itself (say, if Foo was abstract).
Now suppose I have this:
struct FooList { std::vector<boost::shared_ptr<Foo>> foos; }
std::size_t hash_value(const FooList& list)
You should probably be including something representing the dynamic type in the hash value, but that depends on how you implement 'operator==' for FooList. If you don't then defining 'hash_value' doesn't make much sense.
That's what I am trying to do: I'm trying to use the hash_value() for the actual type of the Foos in foos (eg. go through foos, and call hash_value(const Foo1&) if the pointer in foos is a pointer to a Foo1 upcasted to Foo, and so on), but all I am apparently doing is slicing down to Foo, and as hash_value(const Foo&) does not exist, I get a compile-time error. FooList::operator==() is fairly straightforward, I'd imagine: iterate through the two foos and call a polymorphic equals() function to determine equality. I could do a polymorphic Foo::hash() and then redirect hash_value() for the leaf classes to hash(): class Foo { protected: virtual std::size_t hash() = 0; }; std::size_t Foo1::hash() { … } // public in Foo1 // It would be nice to have a template that does this so I don't have to do this for every leaf class std::size_t hash_value(const Foo1& foo1) { return foo1.hash(); } But it does seem like reinventing the wheel. If this is in fact the preferred solution to the conundrum,