2015-05-27 23 views
0

我使用C++進行編碼。我有一個有很多文件的項目。我有一個名爲列表對的向量如下:如果一個元素存在於一個對的向量中,則在該類的內部找到

std::vector< std::pair< structure1, double> > list; 

,我要檢查是否爲特定的雙重價值z,存在一個元素:el列表這樣的:el.second == z

我想要使用find_if

爲此,我實現了一個方法:Scheduled,它有兩個參數:第一個是存儲在列表中的元素,第二個是要查找的特定值。 我嘗試了幾種方法,但我最終得到一個錯誤總是 1路:裏面的另一種方法,但仍然在同一類

bool classA::Scheduled(std::pair< structure1,double > const el, double const t) 
{ 
    return el.second==t; 

} 

:CLASSA

auto Scheduled1 = std::bind(&classA::Scheduled,this,_1,z); 



bool call=std::find_if(list.begin(),list.end(),Scheduled1)=!list.end(); 

該解決方案提供了以下錯誤:

error: ‘Scheduled1’ does not name a type 

第二個辦法: 直接使用lambda

bool call = std::find_if(list.begin(),list.end(),[this](std::pair<struct1,double> const& el){return el.second==z;})!=list.end(); 

z是CLASSA 該編碼的第二方式的成員變量產生了這樣的錯誤:

error: no matching function for call to 

「find_if(標準::矢量>:迭代,性病::矢量> ::迭代器,classA :: method1(int):: __ lambda0)'

+0

從STD返回類型::綁定不一個成員函數,Scheduled1命名一個值,而不是一個類型。 –

+0

爲了記錄,你正在做的是[currying]的形式(http://en.wikipedia.org/wiki/Currying)(可能會在某些情況下使用該名稱更容易搜索它)。 –

+0

對不起,但如果你需要更多的幫助,你將不得不做得更好。在你添加的代碼中有幾個錯誤,除非你可以發佈有效的代碼,否則我不再嘗試。 '&ClassA :: IsItScheduled' - 'classA'中的'c'現在是大寫的? IsItScheduled是什麼? '... Scheduled1)=!list.end();' - '=!'顯然是不正確的。在lambda示例中,'find_if'的結果不能轉換爲'bool',因此您需要將其與另一個示例中的end iterator進行比較。請創建一個可以複製粘貼的測試用例,並重現錯誤。請參閱[SSCCE](http://sscce.org) – Praetorian

回答

4

沒有必要混合使用bind,bind1stmem_fun來做到這一點(後兩者在C++ 11中不推薦使用)。只是使用lambda

bool call = std::find_if(list.begin(), list.end(), 
         [this](std::pair< strucure1,double > const& el) { 
          return el.second == z; 
         }) != list.end(); 

或者,如果你想打電話Scheduled

bool call = std::find_if(list.begin(), list.end(), 
         [this](std::pair< strucure1,double > const& el) { 
          return Scheduled(el, z); 
         }) != list.end(); 

如果必須使用bind

bool call = std::find_if(list.begin(), list.end(), 
         std::bind(&classA::Scheduled, this, _1, z)) != list.end(); 

在這兩種情況下,你可能想改變Scheduled是一個static成員函數,因爲它不需要訪問任何非靜態成員,在這種情況下bind選項變爲

bool call = std::find_if(list.begin(), list.end(), 
         std::bind(&classA::Scheduled, _1, z)) != list.end(); 

此外,Scheduled或許應該採取std::pair參數通過const&,以避免不必要的副本。

另一種選擇是使用any_of代替find_if,這避免了必須將結果與年底相比迭代符

bool call = std::any_of(list.begin(), list.end(), 
         <insert lambda or bind expression>); 

這裏是什麼地方錯了你嘗試的解釋。

auto Scheduled1=std::bind(Scheduled, _1, z); 

Scheduled是一個非靜態成員函數,這意味着它需要一個隱式的第一個參數,指向它的指針必須調用上的實例,即this指針。此外,創建指向成員函數的語法是&ClassName::MemberFunctionName。所以上面的行應該是

auto Scheduled1=std::bind(&classA::Scheduled, this, _1, z); 

bind返回未指定類型的函數對象,但您使用的對象,就好像它是一個成員函數(mem_fun(&classA::Scheduled1)),這顯然是不正確。只需將上述Scheduled1對象作爲第三個參數傳遞給find_if即可。

+0

感謝提到lambda解決方案! – Alejandro

+0

感謝您的解釋,但很明顯,但是,對於兩個第一個建議,我得到此錯誤: 錯誤:捕獲非變量classA :: z 對於第三個,編譯器顯示: Scheduled1沒有命名一個類型 與之前的 相同的消息第三個這裏是我寫的 bool call = std :: find_if(list.begin(),list.end(),Scheduled1)== list.end() ; – Saddam

+0

@Saddam我沒有意識到'z'是'classA'的成員,您需要在lambda捕獲列表中用'this'替換'z',看到更新後的答案。我不確定其他選項有什麼問題。 'auto Scheduled1 = std :: bind(&classA :: Scheduled,this,_1,z); std :: find_if(list.begin(),list.end(),Scheduled1);'應該編譯。如果您仍然遇到問題,請[編輯](https://stackoverflow.com/posts/30483667/edit)該問題,並添加未編譯的代碼以及確切的錯誤消息。 – Praetorian

0

正如@Praetorian所說,你可以使用lambdas。但是,綁定器允許人們使用現有的謂詞函數,並且有時更易讀(新的std :: bind自動將成員函數綁定到實例,允許使用類型的公共接口盒子外面)。我加你類似的(即編譯)中,我將解釋一些事情的例子(見代碼中的註釋):

#include <iostream> 
#include <vector> 
#include <utility> 
#include <functional> 
#include <algorithm> 

// Replaces your structure... 
struct Xs{}; 


// typedef so that we can alias the ugly thing...  
typedef std::vector<std::pair<Xs, double>> XDoubleVector; 

// --- From your code, I've just named it A for brevity.... 
struct A 
{ 
    bool Scheduled(std::pair<Xs,double> const el, double const t) 
    { 
     return el.second==t; 
    } 
}; 


int main() { 

    using namespace std::placeholders; 
    //Instantiate it.... replaced your list. 
    XDoubleVector doubleVect; 
    //--- and add some elements.... 

    //We need to instantiate A, in order to invoke 
    // a member function... 
    A a; 

    // Returns true if found... 
    return std::find_if(
     doubleVect.begin(), 
     doubleVect.end(), 
     //Notes: 
     //- Scheduled is a member function of A 
     //- For that reason, we need to pass an instance of 
     // A to binder (almost seen as first bound). 
     //- _1 indicates that the first parameter to Scheduled will be    
     // passed in by algorithm 
     //- We've hardcoded the second parameter (it is therefore 
     // bound early). 
     std::bind(&A::Scheduled, a, _1, 20.9)) != doubleVect.end(); 

} 

問候,沃納

相關問題