13

我见过这样的代码:

std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);

::我有一个问题: tolower 之前是什么意思?

不工作,std::tolower::tolower工作正常

4

4 回答 4

12

至于为什么::需要:标准定义了两个tolower,一个函数模板在std::,一个简单的函数在::std::。根据包含的标头(包括从其他标头间接包含的标头,您可能不知道),其中一个、另一个或两者都可能是可见的。Using::确保使用来自 C 标准的旧版本。(如果std:: 考虑 in ,调用将是模棱两可的,因为 transform 本身就是一个模板,编译器将无法推断出模板参数。)

当我在这里时,我可能会提到::tolower像这样使用是未定义的行为,至少在普通字符被签名的情况下。to 的输入 ::tolower是一个 int,并且必须在范围0...UCHAR_MAXEOF. 如果对普通字符进行签名,则某些字符可能具有负编码,这会导致未定义的行为。在实践中,大多数实现都可以做到这一点。对于除0xFF(拉丁语 1 中的ÿ)之外的所有字符。如果您不关心可移植性,一些编译器有一个开关可以使 char 无符号——使用它。否则,编写一个小的功能对象来正确处理它,或者:

struct ToLower
{
    char operator()( char ch ) const
    {
        return ::tolower( static_cast<unsigned char>(ch) );
    }
};

或(更好,但工作量要大得多——只有在您经常使用它时才值得),一个函数对象,其构造函数采用语言环境(默认为全局语言环境)并包含对 an 的引用std::ctype,它用于tolower函数. (当然,如果您真的是国际化的,tolower可能没有任何意义。而且您将使用 UTF-8,它是一种多字节编码,并且不适用于任何可用的可能性。)

于 2011-03-11T09:11:39.520 回答
9

意味着它tolower在全局命名空间中显式使用(可能是 stdc lib 之一)。

例子:

void foo() {
    // This is your global foo
}

namespace bar {
    void foo() {
        // This is bar's foo
    }
}

using namespace bar;

void test() {
    foo();   // Ambiguous - which one is it?
    ::foo(); // This is the global foo()
}
于 2011-03-11T08:53:28.230 回答
4

使用全局命名空间中的版本。(可能包括在内<ctypes.h><cctypes>如果std::不起作用则不包括在内)

于 2011-03-11T08:52:35.007 回答
0

:: 是全局命名空间。

#include <iostream>

void bar()
{
    std::cout << "::bar" << std::endl;
}

namespace foo
{
    void bar()
    {
        std::cout << "foo::bar" << std::endl;
    }
}

int main()
{
    bar();
    foo::bar();
    ::bar();
    using namespace foo;
    foo::bar();
    ::bar(); // bar() would be ambiguous now without ::
}
于 2011-03-11T08:57:46.930 回答