我见过这样的代码:
std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
::
我有一个问题: tolower 之前是什么意思?
不工作,std::tolower
但::tolower
工作正常
我见过这样的代码:
std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
::
我有一个问题: tolower 之前是什么意思?
不工作,std::tolower
但::tolower
工作正常
至于为什么::
需要:标准定义了两个tolower
,一个函数模板在std::
,一个简单的函数在::
和
std::
。根据包含的标头(包括从其他标头间接包含的标头,您可能不知道),其中一个、另一个或两者都可能是可见的。Using::
确保使用来自 C 标准的旧版本。(如果std::
考虑 in ,调用将是模棱两可的,因为 transform 本身就是一个模板,编译器将无法推断出模板参数。)
当我在这里时,我可能会提到::tolower
像这样使用是未定义的行为,至少在普通字符被签名的情况下。to 的输入
::tolower
是一个 int,并且必须在范围0
...UCHAR_MAX
或EOF
. 如果对普通字符进行签名,则某些字符可能具有负编码,这会导致未定义的行为。在实践中,大多数实现都可以做到这一点。对于除0xFF
(拉丁语 1 中的ÿ)之外的所有字符。如果您不关心可移植性,一些编译器有一个开关可以使 char 无符号——使用它。否则,编写一个小的功能对象来正确处理它,或者:
struct ToLower
{
char operator()( char ch ) const
{
return ::tolower( static_cast<unsigned char>(ch) );
}
};
或(更好,但工作量要大得多——只有在您经常使用它时才值得),一个函数对象,其构造函数采用语言环境(默认为全局语言环境)并包含对 an 的引用std::ctype
,它用于tolower
函数. (当然,如果您真的是国际化的,tolower
可能没有任何意义。而且您将使用 UTF-8,它是一种多字节编码,并且不适用于任何可用的可能性。)
意味着它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()
}
使用全局命名空间中的版本。(可能包括在内<ctypes.h>
,<cctypes>
如果std::
不起作用则不包括在内)
:: 是全局命名空间。
#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 ::
}