使用std :: transform和tr1 :: bind来转换std :: complex的向量

时间:2011-04-19 14:09:11

标签: c++ bind transform complex-numbers

给定std :: complex的std :: vector,我想将它转换为仅包含复数的实部的向量,除以一些常数系数。 现在,我这样做:

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);

当然这很好用,但我正在寻找一种方法来使用std :: transform来做同样的事情。我试过了:

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

但它不起作用。我有这个错误:

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

我不明白为什么会出现“未解决的重载函数类型”。

有人可以向我解释有什么问题吗?

2 个答案:

答案 0 :(得分:4)

不幸的是,你不能这样做,至少不能直接做到这一点。标准库成员函数的类型(如complex<double>::real)未指定,因此实现可能提供额外的重载,并且那里的函数可能具有带默认参数的附加参数。

实际上,没有可移植的方法来获取标准库成员函数的地址。

你最好的选择是写一个辅助函数:

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

并绑定到:

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

答案 1 :(得分:1)

std::complex<>::real()超载(参见C ++ 11 [complex])。

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

当您获取重载函数的地址时,C ++需要消除歧义。在你的情况下,你必须说:

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

是的,这太丑了。