The following are two options for what you are requesting: the first in which the element is a template parameter, and the second in which the element is instead passed as an argument when building the map ...
#include <map> #include <string> #include <iostream> template<typename Object, typename MemberType, MemberType Object::*member> struct MemberMap { std::map<MemberType, Object *> mmap; Object * operator[](const MemberType& mv) const { typename std::map<MemberType, Object *>::const_iterator i = mmap.find(mv); return i == mmap.end() ? NULL : i->second; } void store(Object *o) { if (o && mmap.find(o->*member) == mmap.end()) mmap[o->*member] = o; } }; template<typename Object, typename MemberType> struct MemberMapByInst { MemberType Object::*member; std::map<MemberType, Object *> mmap; MemberMapByInst(MemberType Object::*member) : member(member) { } Object * operator[](const MemberType& mv) const { typename std::map<MemberType, Object *>::const_iterator i = mmap.find(mv); return i == mmap.end() ? NULL : i->second; } void store(Object *o) { if (o && mmap.find(o->*member) == mmap.end()) mmap[o->*member] = o; } }; struct Foo { std::string name; Foo(const std::string& name) : name(name) { } }; int main() { Foo foo1("This is a test"); Foo foo2("This is another test"); MemberMap<Foo, std::string, &Foo::name> namemap; namemap.store(&foo1); namemap.store(&foo2); MemberMapByInst<Foo, std::string> namemap2(&Foo::name); namemap2.store(&foo1); namemap2.store(&foo2); std::cout << (namemap["This is a test"] != NULL) << std::endl; std::cout << (namemap["What about this?"] != NULL) << std::endl; std::cout << (namemap2["This is a test"] != NULL) << std::endl; std::cout << (namemap2["What about this?"] != NULL) << std::endl; return 0; }
Basically you need to move at least a member type as a template parameter, because it is necessary to be able to generate C ++ code on the map. At run time, you can decide which member you want to use as a key (second version), but its type must be fixed at compile time.
If instead of the actual member that you want to use as a key, compilation time is known, then the member pointer can be taken into account as a template parameter (first version), generating more efficient code (however, creating a new class for every other member - thus increasing the size compiled code).
source share