No pokud jde jenom o jedinečnost metody, tak ta instance ani není potřeba. Stačí něco takového:
class Method
{
public:
template<typename C, typename T>
static unsigned long Id(T (C::*)())
{
static const id = counter_++;
return id;
}
// A pak zopakovat pro metody s jedním parametrem, se dvěma...
template<typename C, typename T, typename P1>
static unsigned long Id(T (C::*)(P1))
{
static const id = counter_++;
return id;
}
template<typename C, typename T, typename P1, typename P2>
static unsigned long Id(T (C::*)(P1, P2))
{
static const id = counter_++;
return id;
}
private:
static unsigned long counter_;
}; // class Method
unsigned long Method::counter_ = 0;
// Pak se to použije takto:
unsigned long id1 = Method::Id(&MyClass::method1);
unsigned long id1 = Method::Id(&MyClass2::method2);
Pokud ten identifikátor má být různý i pro stejné metody různých instancí téže třídy, tak by se musela ta metoda id upravit třeba nějak takto: template<typename C, typename T>
static unsigned long Id(C* c, T (C::*)())
{
static std::map<C*, unsigned long> m;
const std::map<C*, unsigned long>::const_iterator it = m.find(c);
if (it != m.end())
return it->second;
return m.insert(std::make_pair(c, counter_++)).first->second;
}
Je zde samozřejmě problém, že v případě vytvoření nové instance se stejnou adresou, jakou již měla instance stejného typu, bude vrácená hodnota stejná. To by se dalo řešit odstraňováním těchto hodnot v destruktoru dané třídy, ale to vše už jsou jenom spekulace. Záleží na tom, na co to celé je.
Ale určitě to jde i nějak jinak. Toto je takové rychlé ad-hoc řešení.