13

So I have this code:

#include "boost_bind.h"
#include <math.h>
#include <vector>
#include <algorithm>

double foo(double num, double (*func)(double)) {
  return 65.4;
}

int main(int argc, char** argv) {
  std::vector<double> vec;
  vec.push_back(5.0);
  vec.push_back(6.0);
  std::transform(vec.begin(), vec.end(), vec.begin(), boost::bind(foo, _1, log));
}

And receive this error:

        return unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);
.............................................................^
%CXX-E-INCOMPATIBLEPRM, argument of type "double (* __ptr64 )(double) C" is
          incompatible with parameter of type "double (* __ptr64 )(double)"
          detected during:
            instantiation of ...5 pages of boost

So this error is because 'log' is extern "C"'d in math.h

I was wondering how to declare my function pointer argument in foo() so it handles extern "C"'d functions.

Salgar
  • 7,687
  • 1
  • 25
  • 39
  • 1
    not that it answers your question, but this particular situation doesn't require `boost::bind`, `std::bind2nd` would do the job just fine. – Evan Teran Aug 17 '09 at 17:10

2 Answers2

25

You can try including cmath instead, and using static_cast<double(*)(double)>(std::log) (cast necessary to resolve to the double overload).

Otherwise, you will limit your function to extern C functions. This would work like

extern "C" typedef double (*ExtCFuncPtr)(double);

double foo(double num, ExtCFuncPtr func) {
  return 65.4;
}

Another way is to make foo a functor

struct foo {
  typedef double result_type;
  template<typename FuncPtr>
  double operator()(double num, FuncPtr f) const {
    return 65.4;
  }
};

Then you can pass foo() to boost::bind, and because it's templated, it will accept any linkage. It will also work with function objects, not only with function pointers.

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • Amazing, I tried with a functor but I didn't think of fixing it for all types with a template. Thanks – Salgar Aug 17 '09 at 17:19
5

Try using a typedef:

extern "C" {
  typedef double (*CDoubleFunc)(double);
}

double foo(double num, CDoubleFunc func) {
  return 65.4;
}
Laurence Gonsalves
  • 137,896
  • 35
  • 246
  • 299