Tengo problemas para detectar por qué diablos no se está compilando. Tengo alguna función lambda que devuelve un std::function
según algún argumento.std :: bind a bound function
he reducido mi problema a este fragmento (que no utiliza lambdas, pero reproduce perfectamente mi error):
#include <functional>
#include <iostream>
struct foo {
template<class T>
void bar(T data) {
std::cout << data << "\n";
}
};
void some_fun(const std::function<void(int)> &f) {
f(12);
}
int main() {
foo x;
auto f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
auto w = std::bind(some_fun, f);
w();
}
La llamada a w()
produce una de esas salidas de error gcc preciosas en el que No puedo entender qué está pasando mal. Este es el error repetido por gcc 4.6.1:
g++ -std=c++0x test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:20:7: error: no match for call to ‘(std::_Bind<void (*(std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>))(const std::function<void(int)>&)>)()’
/usr/include/c++/4.6/functional:1130:11: note: candidates are:
/usr/include/c++/4.6/functional:1201:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1215:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1229:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1243:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
Aquí, f
debe haber algún objeto invocable que toma un entero como argumento y llama usarlo. Por otro lado, w
es simplemente un objeto invocable que llama al some_fun(f)
, que es f
el objeto invocable mencionado anteriormente, que tiene la firma esperada por el parámetro some_fun
.
¿Echo de menos algo? Probablemente no sé cómo mezclar realmente std::bind
y std::function
.
Parece que funciona cuando reemplaza auto con 'std :: function' para f. –
Lalaland
Esto podría no ser una respuesta a su problema ... pero ¿ha considerado usar las funciones lambda nativas que vienen con C++ 11 (que hacen que std :: bind sea innecesario)? – coldfix
En Boost tenemos 'protect' para casos como este, pero no parece haber llegado al estándar. –