I'm a little confused why this call to bind doesn't work. I've narrowed the problem down to trying to nest a bind object in a new call to bind.
#include <iostream>
#include <algorithm>
#include <tr1/functional>
using namespace std;
using tr1::bind;
using namespace std::tr1::placeholders;
double times_2(double a) {
return 2*a;
}
void print_num(double a) {
cout << a << endl;
}
template <typename Oper>
void oper_on_list(Oper op) {
int list[] = {0,1,2,3,4};
for_each(list, list+5, bind(print_num, bind(op, _1))); // This works!
for_each(list, list+5, bind(print_num, bind(op, bind(op, _1)))); // This doesn't!
}
int main() {
oper_on_list(bind(times_2, _1));
return 0;
}
Here, I get a no matching function for call to 'bind'
message from my compiler. (either G++ 4.2.1, or Apple LLVM 3.0).
(Actually, no matching function for call to object of type 'std::tr1::_Bind<double (*(std::tr1::_Placeholder<1>))(double)>'
)
The goal here was to reuse a bind object in a different bind. From what I've been able to boil it down to, the problem is using the result of a second bind call as an argument to an already created bind call. Is there any way to get around this?
I think this might also help illuminate the situation a little?:
template <typename T>
void print(T t) {
cout << t << endl;
}
template <typename Oper>
void oper_on_list(Oper op) {
int list[] = {0,1,2,3,4};
for_each(list, list+5, bind(print, bind(op, _1))); // This doesn't work
for_each(list, list+5, bind(print<double>, bind(op, _1))); // This does
for_each(list, list+5, bind<void(*)(double)>(print, bind(op, _1))); // So does this!
}
Here, the issue, I think, is that it has trouble deducing the template specification for print based on the bind(op, _1)
. Though I'm not sure why it can't..
But either way, specifying it seems to solve the problem. Unfortunately, I can't see how I can specify the template in the original example, because I don't know what the Oper
will be!
Any help would be much appreciated! :D Thanks!
============================
Update! It turns out that this compiles correctly on C++11. The question now, is: Why doesn't this compile without C++11? As far as I can tell, there aren't any C++11-specific features. Is there a way to achieve this same task without C++11? A different way to set up the code, perhaps?
============================
Update 2! Well, this works with boost::bind, so I guess it's just an issue with tr1::bind..
Well, this works with boost::bind, anyway.
So apparently it is just a bug in tr1::bind pre-C++11..