Say desea almacenar la siguiente:vector de std :: función <>
typedef std::function<void(int)> MyFunctionDecl;
..en una colección:
typedef std::vector<MyFunctionDecl> FunctionVector;
FunctionVector v;
Esto es posible, pero si quiero encontrar algo con std::find
:
FunctionVector::const_iterator cit = std::find(v.begin(), v.end(), myFunctionDecl);
.. obtenemos un error debido a que el operador ==
.
Como se ha sugerido a mí en una pregunta anterior en relación con esto, esto se puede conseguir en torno al encapsular la declaración de función dentro de otra clase, que ofrece un operador de ==
:
class Wrapper
{
private:
MyFunctionDecl m_Func;
public:
// ctor omitted for brevity
bool operator == (const Wrapper& _rhs)
{
// are they equal?
}; // eo ==
}; // eo class Wrapper
Así que lo que quiero hacer de alguna manera genera un hash para "MyFunctionDecl" para que pueda implementar correctamente el operador ==
. Podría tener algún tipo de identificador único y pedirle a la persona que llama que proporcione un identificador único para el delegado, pero parece un poco molesto y propenso a errores.
¿Hay alguna manera de que pueda hacer esto? ¿Para que las mismas funciones devuelvan la misma ID con fines comparativos? Hasta ahora, la única forma de evitarlo es eliminar la noción de usar std::function
y volver a usar delegados rápidos que admiten comparaciones. Pero luego pierdo la habilidad de usar lambdas.
¡Cualquier ayuda apreciada!
EDITAR
dado la respuesta más adelante, esto es lo que he llegado con ... cualquier advertencia que podría haber perdido? Estoy en el proceso de ponerlo a su propio ritmo ahora:
class MORSE_API Event : boost::noncopyable
{
public:
typedef std::function<void(const EventArgs&)> DelegateType;
typedef boost::shared_ptr<DelegateType> DelegateDecl;
private:
typedef std::set<DelegateDecl> DelegateSet;
typedef DelegateSet::const_iterator DelegateSet_cit;
DelegateSet m_Delegates;
public:
Event()
{
}; // eo ctor
Event(Event&& _rhs) : m_Delegates(std::move(_rhs.m_Delegates))
{
}; // eo mtor
~Event()
{
}; // eo dtor
// methods
void invoke(const EventArgs& _args)
{
std::for_each(m_Delegates.begin(),
m_Delegates.end(),
[&_args](const DelegateDecl& _decl) { (*_decl)(_args); });
}; // eo invoke
DelegateDecl addListener(DelegateType f)
{
DelegateDecl ret(new DelegateType(f));
m_Delegates.insert(ret);
return ret;
}; // eo addListener
void removeListener(const DelegateDecl _decl)
{
DelegateSet_cit cit(m_Delegates.find(_decl));
if(cit != m_Delegates.end())
m_Delegates.erase(cit);
}; // eo removeListener
}; // eo class Event
¿Por qué necesita encontrarlo?Si necesita encontrar una función std :: como esta, deberá encontrarla en función de algún identificador o similar, por ejemplo, una int generada automáticamente para cada nuevo Wrapper que cree. Obtenga la int para una comparación futura y asegúrese de crear solo cada contenedor una vez. – villintehaspam
No se pueden comparar funciones, este es el * problema de detención * (http://en.wikipedia.org/wiki/Halting_problem) –
@Alexandre Creo que el problema de la detención está relacionado, pero definitivamente no es el mismo. Creo que la idea del hash es que no necesitas ejecutar la función para compararlo. –