【问题标题】:Disambiguating std::isalpha() in C++在 C++ 中消除 std::isalpha() 的歧义
【发布时间】:2012-09-28 22:23:34
【问题描述】:

所以我目前正在编写一个接受用户文本输入的程序的一部分。我想忽略所有不是字母的输入字符,所以我认为 std::isalpha() 将是一个很好的方法。不幸的是,据我所知,有两个 std::isalpha() 函数,因此需要将通用函数与特定于语言环境的函数消除歧义:

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

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

我之前在另一个程序中这样做过,但由于某种原因,在这个项目中,我有时会收到“ISO C++ forbids”错误。注意,只是有时。这是有问题的代码区域(它一起出现,中间没有任何东西):

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)) sn-p 时才会编译,此时会出现不良行为。有人可以在这里启发我吗?

【问题讨论】:

  • 为什么要进行比较== true?不要那样做。从可读性的角度来看,它是多余的,并且在与表示“真实”的非零结果进行比较时会导致问题。
  • 您能提供一个SSCCE 的问题吗?在将函数作为谓词传递给算法时,我只需要对 is* 函数应用强制转换,以消除它们与区域感知对应物的歧义,而不是在您描述的用例中。
  • 嗯,我想是坏习惯。我刚刚删除了它,现在它可以编译并且工作正常,所以谢谢!但我真的不明白为什么。即使返回类型是 int ,你也不能和 bool 进行比较,所有非零值都是 true 吗?

标签: c++ std sfml


【解决方案1】:

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

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

如果您想比较 std::alpha()bool 的结果,您应该将返回的结果转换为 bool,或者干脆忽略比较并使用类似 if (std::isalpha(c)) {...} 的内容

【讨论】:

  • 但是如果没有另外指定,if() 括号内的内容是否与 true 相比?
  • 啊,谢谢你的解释:布尔和整数比较!现在我明白了。
  • 嗯?我以为 std::isalpha 返回一个布尔值? - 这就是cplusplus.com/reference/std/locale/isalpha 所说的。 (以及为什么您在答案中讨论 std::alpha )
  • @Tom 您正在链接到特定于语言环境的函数,但我使用的是这个函数:cplusplus.com/reference/clibrary/cctype/isalpha
【解决方案2】:

没有必要去歧义,因为正常通话中没有歧义。

此外,当您从 &lt;ctype.h&gt; 获取函数声明时,无需使用 std:: 前缀,在 C++11 之后,您应该优先使用该头文件(即,不是 &lt;cctype&gt;) - 和就此而言,C++11 之前也是如此,但 C++11 成功了。

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

但是,您需要将 char 参数强制转换为 unsigned char,以免您得到除 7 位 ASCII 之外的任何未定义行为。

例如这样做:

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

【讨论】:

  • 感谢有关未定义行为的提示,我一定会记住这一点。
  • 我不明白使用 std::isalpha 有什么问题?为什么使用 c 而不是 c++ 函数?事实上,我认为 std::isalpha 保证返回一个布尔值。
  • @Tom:使用std::isalpha 并没有错误。您只是增加了代码无法与其他编译器或其他上下文一起使用的风险,因为声明可能来自像&lt;ctype.h&gt; 这样的[.h] 标头,它也允许在@ 中删除名称987654331@ 命名空间。你问这个是对的,但你也可以搜索 SO。 std::isalphatwo overloads。一个返回int,另一个返回bool。然而,这样问是错误的。你应该检查一下文档。 ;-)
  • @Tom:关于“为什么使用 c 而不是 c++ 函数”,两个主要原因是简单和高效。 c++ 对语言环境的理解并不是 c++ 程序员引以为豪的事情。在我看来,它是过度设计的、有限的、极其复杂的、脆弱的、缺乏功能的,并且历史上甚至不支持。 Windows 中的 g++。我还没有检查它在 Windows 中使用 g++ 4.7.1 的情况。但如果它仍然如此,我不会感到惊讶。所以...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多