Search code examples
c++bindtransformcomplex-numbers

Using std::transform and tr1::bind to transform a vector of std::complex


Given a std::vector of std::complex, I would like to transform it to a vector containing only the real part of the complex, divided by some constant coefficient. Right now, I do that:

std::vector<std::complex<double> > vec;
std::vector<double> realVec;
double norm = 2.0;
...
for (std::vector<std::complex<double> >::iterator it = vec.begin(), itEnd = vec.end(); it != itEnd; ++it)
    realVec.push_back((*it).real() / norm);

This works fine of course, but I am looking for a way to use std::transform to do the same thing. I tried:

transform(vec.begin(), vec.end(), back_inserter(realVec), tr1::bind(divides<double>(), tr1::bind(&complex<double>::real, tr1::placeholders::_1), norm));

But it won't work. I have this error:

erreur: no matching function for call to ‘bind(<unresolved overloaded function type>, std::tr1::_Placeholder<1>&)’|

I don't understand why there is a "unresolved overloaded function type".

Could someone explain to me what is wrong?


Solution

  • Unfortunately, you can't do this, at least not directly. The types of Standard Library member functions (like complex<double>::real) are left unspecified, so an implementation may provide additional overloads and the functions that are there may have additional parameters with default arguments.

    In effect, there is no portable way to take the address of a Standard Library member function.

    Your best bet would be to write a helper function:

    template <typename T>
    T get_real(const std::complex<T>& c) { return c.real(); }
    

    and bind to that:

    std::tr1::bind(&get_real<double>, std::tr1::placeholders::_1)