5

Estoy tratando de crear un predicado para std::find_if usando boost::bind junto con boost::contains (de la biblioteca boost/algoritm/string). El siguiente fragmento muestra dos formas en que trato de lograr esto.Cómo forzar la sobrecarga de función de la plantilla para boost :: bind?

#include <boost/algorithm/string.hpp> 
#include <boost/bind.hpp> 
#include <boost/function.hpp> 

#include <iostream> 
#include <string> 

int main(int argc, char** argv) { 
     std::string s1("hello mom"); 
     std::string s2("bye mom"); 

     boost::function<bool (std::string, std::string)> f = &boost::contains<std::string, std::string>; 
     std::cout << s1 << " contains " << "hello, " << std::boolalpha << f(s1, "hello") << std::endl; 
     std::cout << s2 << " contains " << "hello, " << std::boolalpha << f(s2, "hello") << std::endl; 

     boost::function<bool (std::string)> contain_hello = boost::bind(boost::contains<std::string, std::string>, _1, std::string("hello")); 
     std::cout << s1 << " contains " << "hello, " << std::boolalpha << contain_hello(s1) << std::endl; 
     std::cout << s2 << " contains " << "hello, " << std::boolalpha << contain_hello(s2) << std::endl; 
     return EXIT_SUCCESS; 
} 

Al compilar este código con g ++ 3.4.5 obtengo el siguiente resultado.

error: conversion from `<unresolved overloaded function type>' to non-scalar type `boost::function<bool()(std::string, std::string), std::allocator<void> >' requested 
error: no matching function for call to `bind(<unresolved overloaded function type>, boost::arg<1>&, std::string)' 

Cuando cambio a boost::icontains que sólo tiene una sobrecarga de everyting funciona bien. Sé cómo resolver una situación similar cuando hay múltiples sobrecargas de la función sin plantilla. ¿Alguien me puede ayudar a escribir esto correctamente? ¿O debería escribir mi propia función de comparación?

Respuesta

8

Debe escribir static_cast<bool(*)(const std::string&, const std::string&)>(&boost::contains<..>) para resolver la sobrecarga.

Sí, esto es un dolor real con plantillas y sobrecarga. Las notas escritas con OOP y la sobrecarga en mente son difíciles de usar con plantillas y boost :: bind.

Todos esperamos expresiones en C++ 0x lambda, que deberían resolver mejor las cosas.

+0

Pequeña corrección (al menos en g ++ 3.4.5) static_cast (boost :: contains <..>). Ahora funciona perfectamente. Muchas gracias por una rápida pista. – lollinus

+0

Ok. Gracias. He actualizado la respuesta con eso. Usualmente lo he usado con ptrs de función de miembro, así que mi sintaxis func-ptr normal estaba un poco oxidada, aparentemente. ;) – Macke

+0

Su franqueza sobre la naturaleza PITA de las plantillas y la sobrecarga es muy tranquilizadora. Antes de ver eso, pensé que debía haber estado haciendo algo mal. –

0

Ese código se ve bien (correcto + conforme) para mí, y se compila con Visual Studio 2008 (con extensiones de lenguaje de Microsoft deshabilitadas).

Intente utilizar una versión más actualizada de gcc.

+0

El problema es que en mi código de producción no puedo usar otro compilador. – lollinus

+1

En tal caso, confíe menos en la magia de la plantilla: escriba una función de envoltura que solo usa el código de impulso, y pase la función de envoltura como argumento a 'find_if'. – gimpf

+0

Entiendo perfectamente que puedo escribir mi propio functor/envoltorio para hacer correspondencias. Solo quería aprender lo que me falta en mi razonamiento al escribir este código. También estoy de acuerdo en que la legibilidad del código sufre al escribir esto como en la solución aceptada. – lollinus

Cuestiones relacionadas