Possible Duplicate:
unresolved overloaded function type c++
Consider the code snippet below:
#include <algorithm>
#include <cctype>
#include <string>
using namespace std;
void test(){
std::string str = "Hello World!";
std::transform(str.begin(), str.end(), str.begin(), tolower);
}
There is an error about tolower when compiling with G++: unresolved overloaded function.
If using namespace std; is removed, the code works fine.
Then, my questions are:
- What is the relationship between
namespace stdwith C functions? - What is the difference between
#include<ctype.h>and#include<cctype>? Although both of them don’t work in the example above. - Why
std::toloweralso doesn’t work? What’s the difference betweenstd::tolowerandtolower?
There is no relationship between
namespace stdand C functions. Butyour code isn’t C, it’s C++, so you also have to consider C++ functions.
Like
std::tolower, for example, in<locale>. Your problem is due toa concurrence of things:
One of the headers you include includes
<locale>. C++ headers areallowed to include other C++ headers, and which header includes which
other header may vary from one implementation to the other, so the
code you’ve written might compile with one compiler, and not with
another.
You’re trying to pass the function as a pointer to function argument,
to a function template where the argument is a template type
parameter. Simply put, in order to do overload resolution on
tolowerhere, the compiler must match it to the type of theargument, and in order to know the type of the argument, the compiler
must do template type deduction based on the exact type of the
function, which it can only know once it has done overload resolution.
If you want the function in
<ctype.h>(which you don’t, since it wouldresult in undefined behavior), you can get it either by including
<ctype.h>(which guarantees that it is present in the globalnamespace) and using
::tolower, or by explicitly specifying theoverload you want, e.g.
static_cast<int (*)(int)>( tolower )(In thisparticular case,
static_castdoesn’t mean type conversion, butexplicit overload resolution.)
In practice, of course, you don’t do this sort of thing. If you’re
doing any text processing at all, you’ll define all of the necessary
functions as functional object types, which avoid undefined behavior by
either converting the input to
unsigned char:or by using the functions in
<locale>which do work withchar:Finally, WRT your second question: the difference depends on the version
of C++ you’re using and the compiler. Globally, however:
<ctype.h>will introduce the functions into the global namespace;
<cctype>willintroduce them into the namespace
std::, and maybe (or maybe not) intothe global namespace. (And your third question has already been
answered above:
std::tolowerrefers to a set of overloaded functionsdefined in
<locale>and<cctype>;::tolowerrefers to a singlefunction defined in
<ctype.h>, and justtoloweris the equivalent of::tolower, unless you’ve doneusing namespace std, in which case,it will refer to the overload set of all of the functions mentionned
above.