开发者

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

开发者 https://www.devze.com 2023-02-27 05:26 出处:网络
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.

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 funct开发者_开发技巧ion 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?


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)


std::complex<>::real() is overloaded (cf. C++11 [complex]).

template <typename T>
class complex {
    // ...
    T real() const; // getter
    void real( T ); // setter
    // ...
};

C++ requires a disambiguation when you take the address of an overloaded function. In your case, you have to say:

tr1::bind( static_cast<double(std::complex<double>::*)()const>( &std::complex<double>::real ),
           tr1::placeholders::_1 )

Yes, this is ugly.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号