2011-04-19 66 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

相關問題