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:
namespace std
with C functions?#include<ctype.h>
and #include<cctype>
? Although both of them don't work in the example above.std::tolower
also doesn't work? What's the difference between std::tolower
and tolower
?Namespace is a feature added in C++ and is not present in C. A namespace is a declarative region that provides a scope to the identifiers (names of functions, variables or other user-defined data types) inside it.
The problem with putting using namespace in the header files of your classes is that it forces anyone who wants to use your classes (by including your header files) to also be 'using' (i.e. seeing everything in) those other namespaces.
The using directive using namespace std makes names within namespace std candidates for matching names used in the current scope. The name vector exists within namespace std (as a templated class).
A namespace is a declarative region that provides a scope to the identifiers (the names of types, functions, variables, etc) inside it. Namespaces are used to organize code into logical groups and to prevent name collisions that can occur especially when your code base includes multiple libraries.
There is no relationship between namespace std
and C functions. But
your 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 to
a concurrence of things:
One of the headers you include includes <locale>
. C++ headers are
allowed 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
tolower
here, the compiler must match it to the type of the
argument, 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 would
result in undefined behavior), you can get it either by including
<ctype.h>
(which guarantees that it is present in the global
namespace) and using ::tolower
, or by explicitly specifying the
overload you want, e.g. static_cast<int (*)(int)>( tolower )
(In this
particular case, static_cast
doesn't mean type conversion, but
explicit 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
:
struct ToLower
{
char operator()( char ch ) const
{
return ::tolower( static_cast<unsigned char>( ch ) );
}
};
or by using the functions in <locale>
which do work with char
:
class ToLower
{
std::locale myLocale; // necessary to guarantee the lifetime of the facet.
std::ctype const* myCType;
public:
ToLower( std::locale const& loc = std::locale() )
; myLocal( loc )
, myCType( &std::use_facet<std::ctype>( loc ) )
{
}
bool operator()( char ch ) const
{
return myCType->tolower( ch );
}
};
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>
will
introduce them into the namespace std::
, and maybe (or maybe not) into
the global namespace. (And your third question has already been
answered above: std::tolower
refers to a set of overloaded functions
defined in <locale>
and <cctype>
; ::tolower
refers to a single
function defined in <ctype.h>
, and just tolower
is the equivalent of
::tolower
, unless you've done using namespace std
, in which case,
it will refer to the overload set of all of the functions mentionned
above.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With