2011-04-19 140 views
3

给定一个std :: complex的std :: vector,我想将它转换为一个只包含实部的复数,除以一些常数系数。 现在,我做到这一点:使用std :: transform和tr1 :: bind来转换一个std :: complex的向量

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(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>&)’| 

我不明白为什么有一个“无法解析的重载函数类型”。

有人可以向我解释什么是错的?

+1

我知道这可能是异端,但IMO使用版本的for循环是多少清晰。 – 2011-04-19 15:40:40

回答

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

std::complex<>::real()被重载(参见C++ 11 [复杂])。

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) 

是的,这是丑陋的。

+0

不幸的是,这并不容易,因为允许一个实现提供额外的重载或为现有的重载添加带有默认参数的附加参数。 :( – 2011-04-19 14:28:42

+0

@James:当然,但是OP询问_why_他得到了那个错误,Legalese很好,但是说“你不能在命名空间std中命名类的成员函数的类型”忽略了OP的问题IMO的观点,这是在获取重载函数的地址时需要的消歧。 – 2011-04-19 22:37:09

相关问题