::运营商必须与tolower()一起使用?

use*_*566 4 c++ operators

transform(mystr.begin(), mystr.end(), mystr.begin(), tolower);
Run Code Online (Sandbox Code Playgroud)

我使用transform函数使字符串全部为小写字母,但即使在写入"using namespace std;"之后 在我的程序的顶部,我得到了一大堆错误(如上所述).当我在tolower参数之前包含::运算符(例如下面)时,我没有.为什么是这样?我认为tolower函数在std命名空间中,它会像我上面那样工作.

transform(mystr.begin(), mystr.end(), mystr.begin(), ::tolower);
Run Code Online (Sandbox Code Playgroud)

我有以下内容:

#include <iostream>
#include <fstream
#include <sstream>
#include <algorithm>
#include <vector>
Run Code Online (Sandbox Code Playgroud)

在错误消息中,我看到:

error: no matching function for call to 'transform(std::basic_string<char>::iterator, ...
Run Code Online (Sandbox Code Playgroud)

那么它就是'tolower'在参数列表中的位置

, <unresolved overloaded function type>);'
Run Code Online (Sandbox Code Playgroud)

M.M*_*M.M 6

嗯,这有点复杂.添加#include <cctype>可能似乎可以解决您的问题.然而,还有更多的事情发生.

有以下两个版本tolower:

int std::tolower(int ch);                           // #include <cctype>

template<typename charT>
charT std::tolower(charT ch, const std::locale& loc);    // #include <locale>
Run Code Online (Sandbox Code Playgroud)

但也可能有这个版本:

int ::tolower(int ch);    // #include <cctype> or #include <ctype.h>
Run Code Online (Sandbox Code Playgroud)

因为允许实现将名称std注入全局名称空间.此外,您不能指望cctypelocale包括或不包括,因为任何标准包括也可能包括任何其他标准包括.


看起来您打算使用该版本<cctype>.但是,这将是一个错误.如果您检查该版本的文档,tolower您将看到在传递给函数之前应将参数转换unsigned char为该参数.

IOW,将char负值传递给cctype版本tolower会导致未定义的行为.(虽然常见的实现支持它,因为它是一个常见的错误).

要更正代码并仍使用cctype版本,您可以编写:

#include <cctype>

// ...

transform(mystr.begin(), mystr.end(), mystr.begin(), 
    [](char ch) { return std::tolower( (unsigned char)ch ); } );
Run Code Online (Sandbox Code Playgroud)

虽然使用起来似乎有点简单:

for (char &ch : mystr)
    ch = std::tolower( (unsigned char)ch );
Run Code Online (Sandbox Code Playgroud)

<locale>版本看起来像(记住它是一个功能模板):

#include <locale>
#include <functional>

// ...

transform(mystr.begin(), mystr.end(), mystr.begin(), 
    std::bind( std::tolower<char>, std::placeholders::_1, std::locale() ) );
Run Code Online (Sandbox Code Playgroud)

要么

std::locale loc;

for ( char &ch : mystr )
    ch = std::tolower(ch, loc);
Run Code Online (Sandbox Code Playgroud)


Ach*_*ill 5

这是为了解决's 和 's模板之间重载tolower之间 的冲突<cctype>int tolower(int c)<locale><typename charT> charT tolower(charT c, locale const& loc)

::tolower 使用全球范围