2015-12-17 69 views
8

考慮以下幾點:使用std :: ptr_fun爲一個成員函數

class A 
{ 
    public: 
    bool is_odd(int i) 
    { 
     return (i % 2) != 0; 
    } 

    void fun() 
    { 
     std::vector<int> v2; 
     v2.push_back(4); 
     v2.push_back(5); 
     v2.push_back(6); 

     // fails here 
     v2.erase(std::remove_if(v2.begin(), v2.end(), std::not1(std::ptr_fun(is_odd))), v2.end()); 
    } 
}; 

上述代碼無法否定的is_odd()的效果,因爲它是一個成員函數。致電std::ptr_fun()失敗。

如何讓它工作?請注意,我想is_odd()是一個非靜態成員函數。

+3

使'is_odd'成爲一個靜態函數?或者是非會員功能?沒有理由它應該是一個成員函數。 –

+0

@HappyCoder:然後將其設爲靜態成員函數。 –

+0

你可以編寫一個仿函數類,它類似於* [this](int n){return is_odd(n);}'的類型並使用它。 –

回答

8

有使用A::is_odd(int)作爲一元謂詞,特別是當需要與std::not1()使用它的多個問題:

  1. A::is_odd(int)的呼叫需要兩個參數:隱式對象(「this」)和可見int的說法。
  2. 它不是定義argument_typeresult_type的函數對象。

正確使用該成員函數作爲一元謂詞需要兩個步驟:

  1. 適應成員函數指針是一個合適的功能對象,例如,使用的std::mem_*fun功能之一。
  2. 將第一個參數綁定到合適的對象,使用非C++ 11編譯器可能使用std::bind1st()

對於C++ 11編譯器來說,事情要容易得多,因爲std::bind()會照顧到這兩者。假設它是從A的成員所使用:

... std::not1(std::bind(&A::is_odd, this, std::placeholders::_1)) ... 

同樣與預先C++編譯器11是稍硬。在std::remove_if()中的用法看起來像這樣:

v2.erase(
    std::remove_if(v2.begin(), 
        v2.end(), 
        std::not1(std::bind1st(std::mem_fun(&A::is_odd), this))), 
    v2.end()); 
+0

不錯的使用'std :: mem_fun' :-) –

+0

@KerrekSB:是的。我沒有注意到它是由'A'的成員調用的。我更新了答案。謝謝。 –

0

只是要is_odd靜態的,所以它不需要一個隱含的this參數:

static bool is_odd(int i) 

它不使用任何成員變量或其他成員函數反正。

相關問題