Question

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..

Was it helpful?

Solution

Well, this works with boost::bind, anyway.

So apparently it is just a bug in tr1::bind pre-C++11..

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top