I try to understand how to use std::tolower...
#include
#include
#include
#include
std::tolower is overloaded in C++, it's declared in as
int tolower(int);
and also in as
template CharT tolower(CharT, const locale&);
so when you say "std::tolower" you get an ambiguous reference to an overloaded function.
- Why
::tolowerversion is working?
When you include the one-argument overload is declared in namespace std and might also be declared in the global namespace, depending on the compiler. If you include then it's guaranteed to be included in the global namespace, and ::tolower will work (although note Dietmar's points about when it's not safe). The two-argument overload from is never declared in the global namespace, so ::tolower never refers to the two-argument overload.
2. Why
std::toloweris not working in std::transform?
See above, it's an overloaded name.
3. What
static_castreally is trying to do?(std::tolower))
It tells the compiler you want the int std::tolower(int) overload, not any other overload of std::tolower.
Why does it work with GCC and not with Visual Studio 2013?
Probably because you didn't include , or (less likely) it could be a Visual Studio bug.
4. How could I use
std::lowerinstd::transformwith Visual Studio 2013 then?
If you know you only have characters with values between 0 and 127 then you can include and use ::tolower (because the two-argument version is not declared in the global namespace, only in namespace std) or disambiguate which overload you want with the static cast. An alternative to the cast is to use a local variable:
typedef int (*tolower_type)(int);
tolower_type tl = &std::tolower;
std::transform(b, e, b, tl);
A safer and portable alternative is to use a custom function object (or lambda expression) to call the desired overload safely:
std::transform(b, e, b, [](unsigned char i) { return std::tolower(i); });
This uses std::tolower with an argument, so the compiler can do overload resolution to tell which overload you want to call. The parameter is unsigned char to ensure we never pass a char with a negative value to tolower(int), because that has undefined behaviour.
See http://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.simple for more details.