std::tolower overloaded in C ++, it is declared in <cctype> as
int tolower(int);
as well as in <locale> as
template<CharT> CharT tolower(CharT, const locale&);
so when you say " std::tolower " you get an ambiguous reference to the overloaded function.
- Why does
::tolower version work?
When you enable <cctype> , single-port overloads are declared in the std and can also be declared in the global namespace, depending on the compiler. If you include <ctype.h> , then it is guaranteed to be included in the global namespace, and ::tolower will work (although it should be noted that Dietmar indicates when it is unsafe). An overload with two arguments from <locale> never declared in the global namespace, so ::tolower never refers to an overload with two arguments.
2. Why does std::tolower not work in std :: transform?
See above, this is an overloaded name.
3. What does static_cast<int(*)(int)>(std::tolower)) really try to do?
It tells the compiler that you want an int std::tolower(int) overload, not any other std::tolower overload.
Why does it work with GCC and not with Visual Studio 2013?
Probably because you did not include <cctype> or (less likely) this could be a Visual Studio error.
4. How could I use std::lower in std::transform using Visual Studio 2013?
If you know that you only have characters with values from 0 to 127, you can include <ctype.h> and use ::tolower (since the version with two arguments is not declared in the global namespace, only in the std ) or eliminate which overloads you want with a static throw. An alternative to 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 safely invoke the desired overload:
std::transform(b, e, b, [](unsigned char i) { return std::tolower(i); });
In this case, std::tolower with an argument, so the compiler can perform an overload to indicate which overload you want to call. The unsigned char parameter to ensure that we never pass a char with a negative value to tolower(int) , as this has undefined behavior.
See http://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.simple for more details.