2013-04-11 94 views
0

我有以下問題:謂詞STL算法

find_if(s.begin(), s.end(), isalpha); 

s是一個庫的字符串。當我嘗試使用isalpha(在「cctype」頭文件中)時,它表示「類型不匹配」。問題是,因而isalpha需要一個int和返回INT:INT因而isalpha(INT)

我解決它通過聲明另一個函數:

bool IsAlpha(char c) { 
    return isalpha(c); 
} 

然而,有沒有更好的方式來做到這一點?我寧願更好的代碼清晰度&簡單,沒有聲明這個「包裝」功能。

謝謝!

+0

我在做什麼錯了? http://liveworkspace.org/code/28S1na$0 – ForEveR 2013-04-11 05:50:39

+0

艾倫,你能引用確切的編譯器錯誤和你得到它的確切代碼嗎?直到,-1。 – 2013-04-11 05:57:23

+0

我很確定至少有一個編譯器希望你投它:'(int(*)(int))isalpha' – chris 2013-04-11 06:04:31

回答

2

我猜想「適當的」 C++的方法是使用在區域設置中定義的isalpha

std::find_if(
    s.begin(), 
    s.end(), 
    [](char c) { return std::isalpha(c, std::locale()); } 
); 

有點冗長也許。

+0

可能有點冗長,但您可以隨時保存lambda表單以備後用,或編寫一個包裝器。 – 2013-04-11 07:23:06

+0

定義多態函數可能是值得的('struct isalpha_functor {template bool operator()(CharT c){return std :: isalpha(c,std :: locale());}};')因爲它可以用於所有類型的字符(char,wchar_t,char16_t和char32_t)。 – 2013-04-11 08:18:25

0

您的解決方案對我來說看起來很好。不同之處在於它有一個非常常見的錯誤

bool IsAlpha(char c) { 
    return isalpha(c); 
} 

應該是

bool IsAlpha(char c) { 
    return isalpha((unsigned char)c); 
} 

因而isalpha僅針對無符號字符值(其通常是0到255)和EOF(這通常是-1)中所定義。嚴格地說,將任何其他負值傳遞給isalpha是未定義的。然而,在實踐中你會發現,如果你給你的例程賦予代碼255的字符(假設你的字符類型是帶符號的),你最終會將-1的值傳遞給isalpha,它總是返回false。

+0

你見過ForEveR對這個問題的評論嗎?如果你這樣做了,你會知道解決方案是錯誤的,因爲問題並不存在。 – 2013-04-11 05:58:20

+1

這是關於什麼的? isalpha需要一個'int',而不是'unsigned char'。當它傳遞一個可以隱式轉換爲'int'的char時,它工作得很好。 – 2013-04-11 06:00:31

+0

@JanHudec我假設當他說他有編譯器錯誤時OP沒有錯。 – john 2013-04-11 06:00:50

0

如何使用函數?

struct IsAlpha { 
     bool operator() (char c) const { return /* isAlpha logic here */; }   
    }; 
    //... 
    find_if(begin, end, IsAlpha()); 

看一看使用仿函數與STL算法的優點here

+0

除了在這種情況下,我根本沒有看到任何優勢。 – 2013-04-11 06:05:50

+0

@Jan,引用一些優點,函子可以是多態的,編譯器可以內聯函數(不可能使用函數),作爲方便的模板參數,列表繼續... – Arun 2013-04-11 06:54:19

+0

但是在_this_情況下,它們不是必需的。雖然,實際上_polymorphic_模板在這裏會很好,因爲'std :: isalpha'是一個模板。 – 2013-04-11 07:16:39

1

只有這樣,我可以想像的是,你使用using namespace std,因爲你寫find_if,不std::find_if在這種情況下,你有以下錯誤 Live example。你不會寫封裝,你可以簡單地使用::isalphaLive example或者你可以將第二個參數綁定到默認語言環境,比如here