I try to understand how to use std::tolower
...
#include <iostream>
#include <string>
#include <algorithm>
#include <locale>
int main()
{
std::string test = "Hello World";
std::locale loc;
for (auto &c : test)
{
c = std::tolower(c, loc);
}
std::transform(test.begin(), test.end(), test.begin(), ::tolower); // 1) OK
std::transform(test.begin(), test.end(), test.begin(), std::tolower); // 2) Cryptic compile error
std::transform(test.begin(), test.end(), test.begin(), static_cast<int(*)(int)>(std::tolower)); // 3) Cryptic compile error. Seems OK with other compilers though
return 0;
}
So:
::tolower
version is working? std::tolower
is not working in std::transform? static_cast<int(*)(int)>(std::tolower))
really is trying to do? Why
does it work with GCC and not with Visual Studio 2013?std::lower
in std::transform with Visual Studio 2013 then?In addition, Visual Studio 2012 Update 3 contains improvements for project compatibility between Visual Studio 2012 and Visual Studio 2013, and resolves compatibility issues for Visual Studio 2012 on Windows 8.1. .NET 4.5.1 is a highly compatible in-place update of .NET 4 and .NET 4.5.
When installed on Windows 8.1, Visual Studio 2012 continues to support creation of Windows Store apps for Windows 8 and Windows Phone 8. In addition, Visual Studio 2012 Update 3 contains improvements for project compatibility between Visual Studio 2012 and Visual Studio 2013, and resolves compatibility issues for Visual Studio 2012 on Windows 8.1.
Windows Store app projects for Windows 8.1 and Windows Phone 8.1 cannot be opened in earlier versions of Visual Studio. You can install and use Visual Studio 2013 alongside Visual Studio 2012. When installed on Windows 8.1, Visual Studio 2012 continues to support creation of Windows Store apps for Windows 8 and Windows Phone 8.
Visual Studio 2013 supports migration of Windows Phone 7 and 7.5 projects to Windows Phone 8. Requires Visual Studio 2013 Update 2 or later. Windows Phone emulator installed on demand. Supports migration of Windows Phone 8 projects to Windows Phone Silverlight 8.1.
First off, note, that none of these approaches does the right thing in a portable way! The problem is that char
may be signed (and typically is) but the versions of tolower()
only accept positive values! That is you really want to use std::tolower()
using something like this:
std::transform(test.begin(), test.end(), test.begin(),
[](unsigned char c) { return std::tolower(c); });
(or, of course, using a corresponding function object if you are stuck with C++03). Using std::tolower()
(or ::tolower()
for that matter) with a negative value results in undefined behavior. Of course, this only matters on platform where char
is signed which seems, however, to be the typical choice.
To answer your questions:
<cctype>
you typically get the various functions and types from the standard C library both in namespace std
as well as in the global namespace. Thus, using ::tolower
normally works but isn't guaranteed to work.<locale>
, there are two versions of std::tolower
available, one as int(*)(int)
and one as char(*)(char, std::locale const&)
. When using just std::tolower
the compiler has generally no way to decide which one to use.std::tolower
is ambiguous, using static_cast<int(*)(int)>(std::tolower)
disambiguates which version to use. Why use of static_cast<...>()
with VC++ fails, I don't know.std::tolower()
with a sequences of char
s anyway as it will result in undefined behavior. Use a function object using std::tolower
internally on an unsigned char
.It is worth noting that using a function object rather than a function pointer is typically a lot faster because it is trivial to inline the function object but not as trivial to inline the function pointer. Compilers are getting better with inlining the use of function pointers where the function is actually known but contemporary compilers certainly don't always inline function calls through function pointers even if all the context would be there.
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