如何在 std::for_each 中使用 std::toupper?

Mah*_*iee 2 c++ stl c++11

我正在尝试使用 std::toupper 函数将字符串的小写字符转换为大写字符,并使用 std::for_each 算法迭代字符串中的字符。

\n\n
#include <iostream>\n#include <string>\n#include <algorithm>\n#include <locale>\n\nstd::string convert_toupper(std::string *x) {\n  return std::toupper(*x, std::locale());\n}\n\nint main() {\n  std::string x ("example");\n\n  std::for_each(x.begin(), x.end(), convert_toupper);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

当我编译此代码时,我收到此错误:

\n\n
In file included from /usr/include/c++/4.8/algorithm:62:0,\n                 from me2.cpp:3:\n/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of \xe2\x80\x98_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<char*, std::basic_string<char> >; _Funct = std::basic_string<char> (*)(std::basic_string<char>*)]\xe2\x80\x99:\nme2.cpp:13:52:   required from here\n/usr/include/c++/4.8/bits/stl_algo.h:4417:14: error: invalid conversion from \xe2\x80\x98char\xe2\x80\x99 to \xe2\x80\x98std::basic_string<char>*\xe2\x80\x99 [-fpermissive]\n  __f(*__first);\n              ^\n
Run Code Online (Sandbox Code Playgroud)\n\n

使用 std::toupper 和 std::for_each 将字符从小写转换为大写的正确方法是什么?

\n

Bar*_*rry 6

基本上, Astring是 s 的容器char。当您迭代 a 时,您一次string只会迭代一个。char因此,您传入的函子for_each将使用 a 来调用char,而不是 a string*,因此会出现错误:

\n\n
invalid conversion from \xe2\x80\x98char\xe2\x80\x99 to \xe2\x80\x98std::basic_string<char>*\n
Run Code Online (Sandbox Code Playgroud)\n\n

正确的实现应该是:

\n\n
std::for_each(x.begin(), x.end(), std::toupper);\n
Run Code Online (Sandbox Code Playgroud)\n\n

然而,这无济于事。的返回值toupper将被忽略,并且该函数没有副作用。如果您确实想将字符串转换为大写版本,则必须使用std::transform

\n\n
std::transform(x.begin(), x.end(), x.begin(), std::toupper);\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,提供区域设置:

\n\n
char locale_upper(char c) { return std::toupper(c, std::locale()); }\nstd::transform(x.begin(), x.end(), x.begin(), locale_upper);\n
Run Code Online (Sandbox Code Playgroud)\n\n

或者,在 C++11 中:

\n\n
std::transform(x.begin(), x.end(), x.begin(), [](char c){\n    return std::toupper(c, std::locale());\n});\n
Run Code Online (Sandbox Code Playgroud)\n\n

此时您不妨只使用for-loop:

\n\n
for (char& c : x) {\n    c = std::toupper(c, std::locale());\n}\n
Run Code Online (Sandbox Code Playgroud)\n