我见过这样的代码:
std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
我有一个问题:在tolower之前是什么意思 ::
?
且std::tolower
不起作用,但::tolower
无效
答案 0 :(得分:10)
至于为什么::
是必要的:标准定义了两个tolower
,
std::
中的函数模板,以及::
和std::
中的简单函数
::
。取决于包含哪些标头(包括
标题间接包含在其他标题中,您可能不知道
可以看到一个,另一个或两者都可见。使用std::
可确保
使用来自C标准的旧版本。 (如果是::tolower
中的那个
被认为是,调用将是模糊的,因为变换是模板
本身,编译器将无法推断出模板
参数。)
虽然我很喜欢,但我可能会提到像这样使用::tolower
未定义的行为,至少如果签署了普通的char。输入到
0
是一个int,必须在UCHAR_MAX
... EOF
或0xFF
范围内。如果
普通字符签名,一些字符可能有负面
编码,导致未定义的行为。在实践中,大多数
实现使这项工作。对于除struct ToLower
{
char operator()( char ch ) const
{
return ::tolower( static_cast<unsigned char>(ch) );
}
};
以外的所有字符(ÿin
拉丁文1)。如果你不关心可移植性,一些编译器有
一个使char无符号的开关---使用它。否则,写一个小的
正确处理它的功能对象:
std::ctype
或(更好,但更多的工作 - 只有你使用它才值得
很多),一个功能对象,其构造函数采用一个语言环境(默认
到全局语言环境)并包含对tolower
的引用
它用于tolower
函数。 (当然,如果你真的
国际化,{{1}}可能没有任何意义。和
你将使用UTF-8,这是一个多字节编码,并不起作用
有任何可能的可能性。)
答案 1 :(得分: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()
}
答案 2 :(得分:4)
使用全局命名空间中的版本。 (如果<ctypes.h>
不起作用,可能包括<cctypes>
而非std::
答案 3 :(得分: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 ::
}