Vincular y transmitir llamadas a funciones con plantilla
Pregunta
Esto no funciona:http://ideone.com/mUL5Y
Pensé que lo ayudé un poco al deducir ese tipo:http://ideone.com/mGfUj
¡Tampoco funciona!No entiendo por qué no.
¿Cómo debería hacer esto?
Solución
El problema parece ser que std::bind
está pasando internamente el resultados evaluados del Callable
(en realidad es un std::bind<>
tipo) objeto c
cuando lo pases por segunda vez aquí:
part2(std::bind(&Quux::part3<Callable>, this, 3, c))
No se trata de aprobar una versión no evaluada del std::bind
objeto como estás suponiendo.
Por lo tanto desde su f
la función devuelve un void
tipo, el resultado de la c
La expresión se pasa internamente como void
tipo, y no un objeto de función invocable no evaluado.Por lo tanto, cuando intentas llamar al Callable
objeto c
en Quux::part2
, que a su vez intenta evaluar la llamada c
en Quux::part3
, no puede pasar un objeto invocable como segundo argumento para Quux::part3
, ya que el tipo que está pasando es en realidad un void
tipo, y no un tipo invocable.
Para obtener más referencia, consulte aquí: http://en.cppreference.com/w/cpp/utility/functional/bind
Tenga en cuenta particularmente que:
Si
std::is_bind_expression<T>::value==true
(es decir, otrostd::bind()
La subexpresión se utilizó como argumento en la llamada inicial abind
), entonces esa subexpresión de vinculación se invoca inmediatamente y su resultado se pasa a la función.
Si desea retrasar la evaluación para que suceda cuando usted lo desee y no cuando apruebe un std::bind
subexpresión, tendrá que buscar otro método, como una lambda, o std::function<>
objeto, un funtor o algún otro tipo de objeto de clase que sea invocable y pueda almacenar un estado que pueda evaluarse más adelante.