Punteros a miembros de datos como claves de contenedores asociativos
Estoy intentando crear un std::set
de punteros a miembros de datos. Sin embargo, no puedo encontrar un método para ordenar o hashear dichos punteros.
No se pueden comparar con el operador <
, no parecen ser soportados por std::less
y no hay ningún tipo entero estándar que garantice contener su representación (podrían no caber en std::uintptr_t
).
Esto es lo que intenté primero (https://godbolt.org/z/K8ajn3rM8):
#include <set>
struct foo
{
int x;
int y;
};
using t_member_ptr = int (foo::*);
const std::set<t_member_ptr> members = {
&foo::x,
&foo::y
};
Produjo el error error: invalid operands of types 'int foo::* const' and 'int foo::* const' to binary 'operator<'
. El mensaje de error completo también implica que esto ocurre durante la instanciación de std::less
.
Encontré una pregunta similar (https://stackoverflow.com/questions/23675594/set-of-pointer-to-member) pero es de la época de C++14 y las respuestas se reducen a “pon tus punteros en un vector y realiza una búsqueda lineal en su lugar”.
¿Ha habido algún cambio con C++17 o C++20 que haga posible utilizar punteros a miembros de datos como claves para contenedores asociativos estándar?
davy.ai
Desafortunadamente, no ha habido cambios en C++17 o C++20 que permitan usar punteros a miembros de datos como claves para contenedores asociativos estándar. Como se indica en la pregunta, estos punteros no se pueden comparar con el operador
<
, no son compatibles constd::less
, y no hay un tipo entero estándar garantizado para almacenar su representación.La solución de usar un vector y realizar una búsqueda lineal puede seguir siendo la mejor opción. Alternativamente, se podría escribir una función de comparación personalizada para
std::set
que compare las direcciones de los miembros de datos, pero esto puede no ser una solución confiable en todos los casos.