2012-12-10 19 views
4

以下是可能在STL:如何使用STL編寫函子?

int count = count_if(v.begin(), v.end(), bind2nd(less<int>(), 3)); 

這將返回v中是小於3如何構成該返回0和3之間的元素數函子元素的數量?我知道增強有一些這方面的設施,但它可能在純粹的STL?

+1

有'std :: logical_and'。還有'std :: bind',如果你可以使用C++ 11,那麼'bind2nd'就是更好的解決方案。如果你可以使用它,你最好用一個lambda,但是。 – chris

+0

是否允許C++ 11? – hmjd

+0

Visual Studio尚未完全支持C++ 11,所以我更喜歡C++ 03解決方案。我知道lambdas,但我很好奇,如果沒有它們就可以完成。 – oddin

回答

8

如果使用標準庫的函子組成的設施,則沒有,至少不是在C++ 98的意思。在C++ 11可以使用std::bind的函子的任意組成:

using std::placeholders; 
int count = std::count_if(v.begin(), v.end(), 
          std::bind(std::logical_and<bool>(), 
            std::bind(std::less<int>(), _1, 3), 
            std::bind(std::greater<int>(), _1, 0))); 

但是,這並沒有真正付出頭疼這樣簡單的斷言。

如果C++ 11層的功能是允許的,那麼最簡單的方法很可能是一個lambda,不需要進行復雜的函子組成(自己):

int count = std::count_if(v.begin(), v.end(), [](int arg) { 
          return arg > 0 && arg < 3; }); 

但對於C++ 98 Chubsdad的答案可能是最好的解決方案。

+0

+1:很好的解決方案 – Chubsdad

+0

你可以通過定義自定義'less'和朋友的形式'struct less_t {template bool operator()(const T&a,const T&b){return a

+0

當然,你不能爲了簡潔和表現而擊敗lambda。你也不能打敗功能語言;在Haskell中,如果你感覺很花哨,你會寫'\ x - > x> 1 && x <3'或者'liftA2(&&)(> 1)(<3)'。 –

5

這是你問的嗎?我知道這不是純粹的STL,但仍..

struct InRange 
{ 
    InRange(int x, int y) : mx(x), my(y) { } 
    bool operator()(int x) 
    { 
     return (x >= mx) && (x <= my); 
    } 
    int mx, my; 
}; 

int main() { 
    std::vector<int> v; 
    v.push_back(13); 
    v.push_back(14); 
    v.push_back(18); 
    v.push_back(3); 

    int count = std::count_if(v.begin(), v.end(), InRange(0, 3)); 
} 
+0

這也是我要做的。我會命名結構'InRange'。我可能會委託給一個Range類,這個類正在系統的其他地方被重用。 –

+0

@彼得伍德:我同意。 mycheck不是很具描述性的名字。將改變它 – Chubsdad

+0

我想要一個就地解決方案,而不需要額外的結構。 – oddin