消除C++中std::isalpha()的歧义

Disambiguating std::isalpha() in C++

本文关键字:歧义 isalpha std 消除 C++      更新时间:2023-10-16

所以我目前正在编写一个程序的一部分,该程序接受用户文本输入。我想忽略所有非字母的输入字符,所以我认为std::isalpha()是一个很好的方法。不幸的是,据我所知,有两个std::isalpha()函数,因此需要将通用函数与特定于区域设置的函数区分开来:

(int(*)(int))std::isalpha()

如果我不消除歧义,std::isalpha在读取大写字母时似乎返回true,但在读取小写字母时返回false(不过,如果我直接打印返回的值,它会为非alpha字符返回0,为大写字符返回1,为小写字符返回2)。所以我需要这样做。

我以前在另一个程序中也这样做过,但由于某种原因,在这个项目中,我有时会遇到"ISO C++禁止"的错误。注意,只是有时。以下是有问题的代码区域(这显示在一起,没有任何中间内容):

std::cout << "Is alpha? " << (int(*)(int))std::isalpha((char)Event.text.unicode) << "n";
if ( (int(*)(int))std::isalpha((char)Event.text.unicode) == true)
{
std::cout << "Is alpha!n";
//...snip...
}

第一个实例,我将返回的值发送到std::cout,运行良好-我没有收到任何错误,我得到了预期的值(0表示非alpha,1表示alpha),如果这是我试图消除歧义的唯一地方,程序编译并运行良好。

然而,第二个例子提出了这个问题:

error: ISO C++ forbids comparison between pointer and integer

并且只有当我删除(int(*)(int))片段时才编译,在这一点上会出现错误行为。有人能在这里启发我吗?

std::alpha()调用的返回值强制转换为int(*)(int),然后将该指针与true进行比较。将指针与布尔值进行比较没有多大意义,并且会出现错误。

现在,在没有强制转换的情况下,将比较std::alpha()返回的inttruebool是一种整数类型,为了比较两种不同的整数类型,首先将值转换为相同的类型。在这种情况下,它们都被转换为inttrue变为1,如果std::isalpha()返回2,则比较以2 != 1结束。

如果您想将std::alpha()的结果与bool进行比较,您应该将返回的结果强制转换为bool,或者简单地省略比较并使用类似if (std::isalpha(c)) {...}的东西

没有必要消除歧义,因为在正常调用中不存在歧义。

此外,当您从<ctype.h>获得函数声明时,不需要使用std::前缀,在C++11之后是您最好使用的标头(即,不是<cctype>)–就这一点而言,在C++11之前也是如此,但C++11锁定了它

第三,您不应该将结果与true进行比较。

但是,您需要将char参数强制转换为unsigned char,以免得到除7位ASCII之外的任何内容的Undefined Behavior。

例如,这样做:

bool isAlpha( char const c )
{
typedef unsigned char UChar;
return !!isalpha( UChar( c ) );
}