2012-12-13 45 views
3

我想確保一個字符串至少有一個字母。簡單:如何引用find_if謂詞中的迭代器?

if (find_if(field_name.begin(), field_name.end(), isalpha) == field_name.end()) 

但我想用一個locale。我知道我可以輕鬆地編寫一個單獨的函數,但我更喜歡在find_if中使用它。即,

include <locale> 

std::locale loc; 

if (find_if(field_name.begin(), field_name.end(), isalpha(*this_iterator,loc) == field_name.end()) 

問:有什麼方法使this_iterator指的是當時最新的迭代器?

+2

因爲無論如何* * this_iterator被傳遞(因爲它是第一個例子),所以你可以做一個'std :: bind'。 'std :: bind(isalpha,std :: placeholders :: _ 1,loc)' – chris

回答

7

在C++ 11中,您可以使用Timo建議的lambda或std::bind(),如std::bind(isalpha, std::placeholders::_1, loc)。可以使用std::bind2nd()來代替。儘管這會變得有些複雜,因爲它需要一個unary_functionbinary_function作爲參數,而不是任何舊的函數對象。我們可以使用std::ptr_fun()創建一個,但由於某些原因,我們需要明確告訴它模板參數是什麼。我們需要使用std::isalpha()而不是isalpha()來獲取啓用語言環境的版本。因此,完整的表達式看起來像

std::bind2nd(std::ptr_fun<char, const std::locale&, bool>(std::isalpha), loc) 

不用說,C++ 11版本非常簡單。


順便說一句,如果你使用的是C++ 11,那麼你可以使用而不是std::find_if(...) == foo.end()。它應該表現相同,但可讀性略高。

+0

有趣。從未想過std :: any_of。 – chris

+0

'std :: bind2nd(isalpha,loc)'給了我:''錯誤C2825:'_Fn2':必須是一個類或命名空間,後跟'::''「和'std :: bind2nd(isalpha(), loc)'返回''錯誤C2660:'isalpha':函數不接受0個參數'「。我在編碼時犯了一個錯誤嗎? –

+0

@ Macbeth'sEnigma:我發現VisualStudio的錯誤非常遲鈍。但我的第一個想法是,你記得'#包括'? –

6

在C++ 11,你可以使用lambda:

if (std::find_if(field_name.begin(), field_name.end(), 
       [&loc](char c) 
       { 
        return isalpha(c, loc); 
       }) == field_name.end()) 
{ 
    ... 
} 

在預C++ 11你可能使用類似的boost ::綁定或升壓:: lambda來達到同樣的功能。

3

在預C++ 11,你可以用覆蓋()操作者的物體包裹isalpha(),然後用它作謂語,如果你不希望使用std::bind...()或提升,例如:

#include <locale> 

struct isalphaloc 
{ 
    const std::locale &_loc; 

    isalphaloc(const std::locale &loc) : _loc(loc) {} 

    bool operator(const char c) const 
    { 
     return isalpha(c, _loc); 
    } 
}; 

std::locale loc; 
if (find_if(field_name.begin(), field_name.end(), isalphaloc(loc)) == field_name.end())