2014-07-03 40 views
3

假設我有以下代碼:如何在一元謂詞中使用類成員變量?

#include <vector> 
#include <algorithm> 
#include <cmath> 

bool pred(float const &val) 
{ 
    //return fabs(val) < epsilon; 
} 

class Foo 
{ 
public: 
    Foo(float eps) : epsilon(eps) { } 

    int Bar(std::vector<float> vec) 
    { 
     return std::count_if(vec.begin(), vec.end(), pred); 
    } 
private: 
    float epsilon; 
} 

我想有一元謂詞pred()作爲一類方法,以便它可以訪問epsilon成員變量。我見過使用operator()的例子,但如果我理解了它,操作員應該比較整個類實例。我只需要比較給定的std::vectorBar()中的元素。是否有可能創建一個一元謂詞作爲類成員?如果沒有,還有其他方法可以做到嗎?

回答

2

這裏是一個C++ 98的解決方案:

class Pred{ 
    private: 
     float eps; 
    public: 
     Pred(float eps) : eps(eps){ 
     } 

     bool operator()(const float& val){ 
      return val < eps; 
     } 
}; 

而且使用這樣的:

int Bar(std::vector<float> vec) 
{ 
    Pred pred(epsilon); 
    return std::count_if(vec.begin(), vec.end(), pred); 
} 

請注意,此解決方案適用於需要額外數據的謂詞;編寫一個包含附加數據的類作爲類成員,並重載運算符()。您可以使用適當的數據初始化類的對象,然後將其用作謂詞。

+0

非常好,謝謝!儘管C++ 11看起來更優雅,但我正在尋找一個C++ 98解決方案,因此我會接受這個答案。 – wondering

3

,如果你使用的是C++ 11,你應該是最簡單的方式是一個lambda

int Bar(std::vector<float> vec) 
{ 
    return std::count_if(vec.begin(), vec.end(),[this](const float &f) 
    { 
     return fabs(val) < epsilon; 
    }); 
} 
+0

我現在沒有使用它,但我會問編碼準則是否允許使用C++ 11。儘管看到C++ 98解決方案會很高興。 – wondering

2

你的問題是pred()需要兩個參數,但std :: count_if想要一個只有一個的函數。 @ Praetorian的帶有lambda的C++ 11解決方案是最優的。但是如果沒有訪問權限,你應該可以使用std :: bind1st來爲你做operator()解決方案,而不用明確地創建一個類來完成它。

#include <vector> 
#include <algorithm> 
#include <cmath> 
#include <functional> 

bool pred(float const &val, float epsilon) 
{ 
    return fabs(val) < epsilon; 
} 

class Foo 
{ 
public: 
    Foo(float eps) : epsilon(eps) { } 

    int Bar(std::vector<float> vec) 
    { 
     return std::count_if(vec.begin(), vec.end(), std::bind1st(std::less<float>(), epsilon)); 
    } 
private: 
    float epsilon; 
}; 
+0

非常好!現在我不知道接受哪個答案。 :d – wondering