Todos los objetos C++, incluidos los punteros a funciones miembro, se representan en la memoria como una matriz de caracteres. Lo que podría intentar:
bool (Class::*fn_ptr)() = &Class::whatever;
const char *ptrptr = static_cast<const char*>(static_cast<const void*>(&fn_ptr));
Ahora tratan ptrptr
como apuntar a una serie de (sizeof(bool (Class::*)()))
bytes, y el hash o comparar esos bytes. Puede usar unsigned char
en lugar de char
si lo prefiere.
Esto no garantiza falsos positivos: en C++ 03, los punteros a las funciones miembro son POD, lo que significa, entre otras cosas, que se pueden copiar utilizando memcpy. Esto implica que si tienen los mismos valores de byte por byte, entonces son los mismos.
El problema es que la representación de almacenamiento de los punteros de función de miembro podría incluir bits que no participan en el valor, por lo que no necesariamente serán los mismos para diferentes punteros a la misma función de miembro. O el compilador podría, por alguna razón oscura, tener más de una forma de señalar la misma función de la misma clase, que no son iguales en bytes. De cualquier manera, puede obtener falsos negativos. Deberá analizar cómo los punteros de función de miembro realmente funcionan en su implementación. Debe implementar operator==
para punteros de función de miembro de alguna manera, y si puede averiguar cómo, entonces probablemente pueda averiguar una orden y una función de hash.
Eso es potencialmente difícil: los punteros a las funciones de los miembros son incómodos, y es probable que el almacenamiento incluya diferentes cantidades de "espacio libre" no participante según el tipo de función señalada (virtual, heredada). Por lo tanto, probablemente deba interactuar bastante significativamente con los detalles de implementación de su compilador. Este artículo podría ayudarlo a comenzar: http://www.codeproject.com/KB/cpp/FastDelegate.aspx
Una alternativa más limpia podría ser hacer una búsqueda lineal a través de una matriz para "canonicalizar" todos los punteros a su función, luego compararla y basarla según la posición del "canónico" instancia de ese puntero de función en su matriz. Depende de cuáles son sus requisitos de rendimiento. E incluso si hay requisitos, ¿tiene la clase (y sus clases derivadas) tantas funciones que la búsqueda lineal tardará tanto?
typedef bool (Class::*func)();
vector<func> canon;
size_t getIndexOf(func fn_ptr) {
vector<func>::iterator it = find(canon.begin(), canon.end(), fn_ptr);
if (it != canon.end()) return it - canon.begin();
canon.push_back(func);
return canon.size() - 1;
}
Normalmente no hay ninguna razón para hash un puntero, ya que apunta directamente a lo que desea acceder.Proporcione un código que ilustre lo que pregunta. –
¿Cuándo dirías que un puntero de función es 'menos' que otro? –
@bojan: si el único propósito de la comparación es almacenarlos en una lista ordenada, cualquier orden determinista servirá. Por ejemplo, el valor binario. – erikkallen