I've seen code like this:
std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
And I have a question: what does mean ::
before tolower?
and std::tolower
not works, but ::tolower
works OK
I've seen code like this:
std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
And I have a question: what does mean ::
before tolower?
and std::tolower
not works, but ::tolower
works OK
:: is the global namespace.
As to why the
::
is necessary: the standard defines twotolower
's, a function template instd::
, and a simple function in both::
andstd::
. Depending on which headers have been included (and that includes headers indirectly included from other headers, which you may not know about), either one, the other, or both may be visible. Using::
ensures that the older one, from the C standard, is used. (If the one instd::
is considered, the call will be ambiguous, since transform is a template itself, and the compiler will not be able to deduce the template arguments.)While I'm at it, I might mention that using
::tolower
like this is undefined behavior, at least if plain char is signed. The input to::tolower
is an int, and must be in the range0
...UCHAR_MAX
, orEOF
. If plain char is signed, some of the characters may have negative encodings, which results in undefined behavior. In practice, most implementations make this work. For all characters except0xFF
(ÿ in Latin 1). If you're not concerned with portability, some compilers have a switch to make char unsigned---use it. Otherwise, write a small functional object to handle it correctly, either:or (better, but significantly more work---only worth it if your using it a lot), a functional object whose constructor takes a locale (defaulting to the global locale) and contains a reference to an
std::ctype
, which it uses for thetolower
function. (Of course, if you're really internationalized,tolower
probably doesn't have any meaning. And you'll be using UTF-8, which is a multi-byte encoding, and doesn't work with any of the available possibilities.)Use the version from the global namespace. (Probably included
<ctypes.h>
and not<cctypes>
ifstd::
doesn't work)Means that it is explicitly using the
tolower
in the global namespace (which is presumably the stdc lib one).Example: