:: 与 tolower() 一起使用所必需的运算符
:: operator necessary to use with tolower()?
transform(mystr.begin(), mystr.end(), mystr.begin(), tolower);
我正在使用 transform 函数使字符串全部小写字母,但即使在编写"使用命名空间 std;"之后,在我的程序顶部,我也会收到一大堆错误(当像上面一样编写时)。当我在 tolower 参数之前包含 :: 运算符时(如下所示),我没有。这是为什么呢?我认为 tolower 函数位于 std 命名空间中,它会像我上面一样工作。
transform(mystr.begin(), mystr.end(), mystr.begin(), ::tolower);
我有以下内容包括:
#include <iostream>
#include <fstream
#include <sstream>
#include <algorithm>
#include <vector>
在错误消息中,我看到:
error: no matching function for call to 'transform(std::basic_string<char>::iterator, ...
然后它是参数列表中"降低"的位置
, <unresolved overloaded function type>);'
嗯,这有点复杂。添加#include <cctype>
似乎可以解决您的问题。然而,还有更多的事情要做。
有两个版本的tolower
:
int std::tolower(int ch); // #include <cctype>
template<typename charT>
charT std::tolower(charT ch, const std::locale& loc); // #include <locale>
但也可能有这个版本:
int ::tolower(int ch); // #include <cctype> or #include <ctype.h>
因为允许实现将名称从std
注入全局命名空间。此外,您不能指望是否包含cctype
或locale
,因为任何标准包含也可能包括任何其他标准包含。
看起来您打算使用<cctype>
中的版本。 但是,这将是一个错误。如果您查看该版本tolower
的文档,您将看到参数在传递给函数之前应转换为unsigned char
。
IOW,将具有负值的char
传递给 tolower
的 cctype 版本会导致未定义的行为。(尽管常见的实现支持它,因为它是一个常见的错误)。
要更正您的代码并仍然使用 cctype 版本,您可以编写:
#include <cctype>
// ...
transform(mystr.begin(), mystr.end(), mystr.begin(),
[](char ch) { return std::tolower( (unsigned char)ch ); } );
虽然使用起来似乎更简单一些:
for (char &ch : mystr)
ch = std::tolower( (unsigned char)ch );
<locale>
版本如下所示(记住它是一个函数模板):
#include <locale>
#include <functional>
// ...
transform(mystr.begin(), mystr.end(), mystr.begin(),
std::bind( std::tolower<char>, std::placeholders::_1, std::locale() ) );
或
std::locale loc;
for ( char &ch : mystr )
ch = std::tolower(ch, loc);
这是为了解决 tolower
之间的重载之间的冲突 <cctype>
的int tolower(int c)
和<locale>
的模板<typename charT> charT tolower(charT c, locale const& loc)
::tolower
使用全局范围
您包含的头文件是什么?确保,你包括<cctype>
而不是<ctype.h>
..在<cctype>
中,所有函数都在命名空间 std 中定义。
::
是说它在全局命名空间中。它只是说清楚
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 使用C++中的模板和运算符重载执行矩阵运算
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 增量运算符与后缀混淆
- 一个关于在C++中重载布尔运算符的问题
- 运算符C++ "delete []"仅删除 2 个前值
- 模板类无法识别友元运算符
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 关闭||运算符优化
- 通过继承类使用来自不同命名空间的运算符
- C++Cast运算符过载
- 如何使用AngelScript注册SFML Vector2运算符
- 重载元组索引运算符-C++
- 如何使用重载的相等(==)运算符向测试用例添加描述
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 布尔比较运算符是如何在C++中工作的
- 重载运算符new[]的行为取决于析构函数
- :: 与 tolower() 一起使用所必需的运算符