Teniendo en cuenta lo siguiente:¿Puedo escribir un functor de C++ que acepte tanto un puntero sin formato como un puntero inteligente?
struct Foo
{
int bar() const;
};
struct IsEqual : public std::unary_function<Foo*, bool>
{
int val;
IsEqual(int v) : val(v) {}
bool operator()(const Foo* elem) const
{
return elem->bar() == val;
}
};
que tienen un contenedor de Foo*
y utilizo std::find_if
y std::not1
para averiguar si hay elementos en el contenedor donde bar()
vuelve algo diferente de un valor dado. El código es el siguiente:
// Are all elements equal to '2'?
bool isAllEqual(const std::vector<Foo*> &vec)
{
return find_if(vec.begin(), vec.end(), std::not1(IsEqual(2))) == vec.end();
}
de avance rápido hacia el futuro y ahora tengo un recipiente diferente, esta vez contiene std::tr1::shared_ptr<Foo>
. Me encantaría simplemente reutilizar mi functor en una versión sobrecargada de isAllEqual()
. Pero no puedo. Foo*
y shared_ptr<Foo>
son tipos diferentes. Y necesito heredar desde unary_function
para poder usar not1
. Sería más elegante si pudiera evitar escribir el mismo funtor dos veces.
Preguntas:
- ¿Hay alguna manera de escribir
IsEqual
por lo que se puede utilizar tanto punteros primas e inteligentes? - ¿Me esposé usando
std::not1
? ¿Debo simplemente escribirIsNotEqual
?
Restricciones:
- que no pueden utilizar cualquier cosa de la biblioteca de impulso.
- Nuestro compilador no es lo suficientemente bueno para admitir C++ 0x lambdas.
Esto suena como un ejemplo donde las plantillas serían agradables. – GWW
@Kristo: ¿Su compilador es lo suficientemente bueno para proporcionar otras cosas de C++ 0x, como 'std :: begin'? –
@Ben, estamos usando gcc 4.1.2, entonces probablemente no. 'std :: begin' y' std :: end' deben ser triviales para escribir. –