2013-04-11 76 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