2015-05-20 72 views
4

我有一個成員函數如下:傳遞一個C++成員函數指針到STL算法

class XYZ{ 
public: 
    float function(float x); 
private: 
    float m_DensityMin; 
    float m_DensityMax; 
}; 

現在,我試圖用std::transform STL算法來變換std::vector<float> foo通過將成員函數function,並將結果值存儲在向量bar中。

如果我使用函數作爲一個全局函數,並且隨機數據應該表示類的成員變量,它可以正常工作。

但是,由於函數需要使用類的成員變量m_DensityMinm_DensityMax,所以我需要將它用作成員函數。這是我已經試過:

std::transform(foo.begin(), foo.end(), bar.begin(), &XYZ::function); 

,但我在VS2010結束與錯誤:

error C2065: term does not evaluate to a function taking 1 arguments 

至於我可以告訴我傳球只有1個說法。任何指針? 這裏有一個類似的question,我試過用std :: mem_fun,因爲std :: mem_fn對我沒有用,但無濟於事。

+1

*「我已經嘗試使用std :: mem_fun,因爲std :: mem_fn不適用於我,但無濟於事。「*使用'std :: mem_fun'時出現了什麼問題?你有沒有嘗試過使用lambda? – dyp

+1

除非它是一個靜態函數,否則你需要一個參數對象,並將它綁定到任何'mem_fun'返回:'std :: transform(foo.begin(),foo.end(),std :: back_inserter(bar),std :: bind1st(std :: mem_fun(&XYZ :: function),&xyz));',[demo](http://coliru.stacked-crooked.com/a/1733c6da8b46abee) –

+1

'function'應該可能是一個靜態成員函數。 – 0x499602D2

回答

6

std::mem_funstd::mem_fun本身只爲成員函數提供一個包裝,以便在傳遞給它的第一個參數的上下文中調用一個函數,以便傳遞給它的operator()。說了這麼多,你需要的XYZ適當的實例bind傳遞函數對象到std::transform算法之前:

XYZ xyz; 

std::transform(foo.begin(), foo.end(), 
       std::back_inserter(bar), 
       std::bind1st(std::mem_fun(&XYZ::function), &xyz)); 
//     ~~~~~~^  ~~~~~~^     ~~~^ 

DEMO

2

除非函數是static,否則它需要一個類的實例來調用該函數。因爲非靜態函數應該取決於該類的內部狀態。如果函數獨立於類的狀態,它可能應該是靜態的。

如果你不得不離開你的課程,你可以默認構建一個XYZ,只是爲了讓一個實例調用該函數。

std::transform(foo.begin(), 
       foo.end(), 
       std::back_inserter(bar), 
       [](float a){ return XYZ{}.function(a); }); 

但這種感覺哈克,我寧願功能是static,如果它是不依賴於XYZ實例的狀態,只取決於輸入float

+0

'foo'是'vector ',而不是'vector '。 – 0x499602D2

+0

好,趕緊編輯我的帖子。 – CoryKramer

+0

我喜歡lambda版本比std :: bind多得多。我實際上忘記了std :: bind,因爲我學習了lambda,現在我更快樂了!我也喜歡這樣一個事實,即你創建了一個微小的物體,儘管如果它的大小是相關的,那麼通過引用來捕獲它可能會更好。 – DarioP

0

拉姆達版本

std::vector<float> foo; 
std::vector<float> bar; 
foo.push_back(1.0f); 
foo.push_back(2.0f); 
XYZ xyz; 
std::transform(foo.begin(), foo.end(), std::back_inserter(bar), 
     [&xyz](float& a){ return xyz.function(a); }); 
for (auto & x : bar) 
    std::cout<<x<<"\n";