5

Im trying to wrap a passed in function inside a try-catch clause so that I can catch exceptions thrown by it and do some cleanup before re-throwing. I have written sample code that replicates my compile bug.

#include <functional>
#include <iostream>
#include <queue>
#include <string.h>
#include <stdexcept>

using namespace std;

void foo(int a){
    throw runtime_error("died");
}

template<class F,class ...Args>
void gen(F&& f,Args&&... args){
    auto wrap = [](F f,Args... args){

        try{
            f(args...);
        }catch(exception& e){
            std::cout << "Caught exception" <<std::endl;
        }

    };

    auto bound = std::bind(wrap, std::forward<F> (f),
                           std::forward<Args>(args)...);

    bound();
}

int main()
{

    gen(foo,5);

    return 0;
}

I can't seem to figure out how to pass in a function pointer into either the lambda expression or the bind call. It seems to report an error at the call to bound(). Can someone give some advice or tell me if there is something I'm misunderstanding?

sibtx13
  • 123
  • 1
  • 6

1 Answers1

1

Your problem is actually rather simple: the type deduced for F&& happens to be void(int) rather than void(*)(int). However, you cannot copy a function while you can copy a function pointer. That is, there is a one character fix to your problem:

gen(&foo, 5);

Pass a pointer to the function rather than the function.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
  • Thanks, you've pointed out that the issue is with the rvalue binding. Unfortunately, while this fixes my example, my real code would call gen(forward(foo),5) where it has an rvalue of foo passed into it much in the same way as gen(). In that case, &foo doesnt seem to work. – sibtx13 Sep 18 '12 at 00:05
  • No, of course not: You want to get one step further out! At some point, you have an actual function. This is where you need to take the address. – Dietmar Kühl Sep 18 '12 at 00:07