Reputation: 2241
So I am currently writing a part of a program that takes user text input. I want to ignore all input characters that are not alphabetic, and so I figured std::isalpha() would be a good way to do this. Unfortunately, as far as I know there are two std::isalpha() functions, and the general one needs to be disambiguated from the locale-specific one thusly:
(int(*)(int))std::isalpha()
If I don't disambiguate, std::isalpha seems to return true when reading uppercase but false when reading lowercase letters (if I directly print the returned value, though, it returns 0 for non-alpha chars, 1 for uppercase chars, and 2 for lowercase chars). So I need to do this.
I've done so in another program before, but for some reason, in this project, I sometimes get "ISO C++ forbids" errors. Note, only sometimes. Here is the problematic area of code (this appears together without anything in between):
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...
}
The first instance, where I send the returned value to std::cout, works fine - I get no errors for this, I get the expected values (0 for non-alpha, 1 for alpha), and if that's the only place I try to disambiguate, the program compiles and runs fine.
The second instance, however, throws up this:
error: ISO C++ forbids comparison between pointer and integer
and only compiles if I remove the (int(*)(int)) snippet, at which point bad behavior ensues. Could someone enlighten me here?
Upvotes: 3
Views: 1241
Reputation: 229854
You are casting the return value of the std::alpha()
call to int(*)(int)
, and then compare that pointer to true
. Comparing pointers to boolean values doesn't make much sense and you get an error.
Now, without the cast, you compare the int
returned by std::alpha()
to true
. bool
is an integer type, and to compare the two different integer types the values are first converted to the same type. In this case they are both converted to int
. true
becomes 1
, and if std::isalpha()
returned 2
the comparison ends up with 2 != 1
.
If you want to compare the result of std::alpha()
against a bool
, you should cast that returned in to bool
, or simply leave out the comparison and use something like if (std::isalpha(c)) {...}
Upvotes: 3
Reputation: 145429
There is no need to disambiguate, because the there is no ambiguity in a normal call.
Also, there is no need to use the std::
prefix when you get the function declaration from <ctype.h>
, which after C++11 is the header you should preferably use (i.e., not <cctype>
) – and for that matter also before C++11, but C++11 clinched it.
Third, you should not compare the result to true
.
However, you need to cast a char
argument to unsigned char
, lest you get Undefined Behavior for anything but 7-bit ASCII.
E.g. do like this:
bool isAlpha( char const c )
{
typedef unsigned char UChar;
return !!isalpha( UChar( c ) );
}
Upvotes: 2