C++ 什么是“:”:&引用;“中的平均值”:托洛尔;?

C++ 什么是“:”:&引用;“中的平均值”:托洛尔;?,c++,string,stl,std,scope-resolution,C++,String,Stl,Std,Scope Resolution,我见过这样的代码: std::string str = "wHatEver"; std::transform(str.begin(), str.end(), str.begin(), ::tolower); 我有一个问题:tolower之前是什么意思 和std::tolower不起作用,但::tolower正常使用全局命名空间中的版本。(如果std:不起作用,则可能包括,而不是)表示它在全局名称空间中显式使用tolower(可能是stdc-lib) 例如: void foo() { /

我见过这样的代码:

std::string str = "wHatEver";
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
我有一个问题:tolower之前是什么意思


std::tolower
不起作用,但
::tolower
正常

使用全局命名空间中的版本。(如果
std:
不起作用,则可能包括
,而不是

表示它在全局名称空间中显式使用
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()
}

::是全局命名空间

#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 ::
}
#包括
空条()
{

std::cout至于为什么需要
:该标准定义了两个
tolower
std::
中的函数模板,以及
和中的简单函数
std::
。取决于包含的标题(包括 从其他标头间接包含的标头,您可能不知道这些标头 关于),其中一个、另一个或两者都可能可见。使用
可确保 使用C标准中的旧版本。(如果
std::
如果考虑,调用将是不明确的,因为转换是一个模板 而编译器将无法推断模板 参数。)

在这里,我可能会提到像这样使用
::tolower
未定义的行为,至少在纯字符有符号的情况下。的输入
::tolower
是一个int,必须在
0
范围内。…
UCHAR\u MAX
EOF
范围内。如果 纯字符是有符号的,某些字符可能有负数 编码,这会导致未定义的行为。在实践中,大多数 实现使这一点起作用。对于除
0xFF
(ÿin)之外的所有字符 如果你不关心可移植性,有些编译器 使字符无符号的开关——使用它。否则,写一个小的 函数对象来正确处理它,或者:

struct ToLower
{
    char operator()( char ch ) const
    {
        return ::tolower( static_cast<unsigned char>(ch) );
    }
};
struct-ToLower
{
char运算符()(char ch)常量
{
返回:tolower(静态_cast(ch));
}
};
或者(更好,但更多的工作——只有在你使用它的情况下才值得) 函数对象,其构造函数采用区域设置(默认设置) 并包含对
std::ctype
的引用 它用于
tolower
功能。(当然,如果您确实 国际化,
tolower
可能没有任何意义 您将使用UTF-8,这是一种多字节编码,不起作用
有了任何可用的可能性。)

谢谢。我使用Visual C++ 6。S::从全局命名空间中使用ToWar,ToWoor的其他潜在过载在<代码> <代码>(我说潜在的,因为我不知道VC++ 6在这一点上是如何符合的……为什么使用这样一个旧编译器?)“为什么使用这样一个老编译器?”哦,不要问)这是因为非常旧的项目,这是唯一有效的原因(但如果项目必须继续,我会计划进行转换)。我们看到太多的学习者仍在使用它。从技术上讲,它被称为。这应该给你一个术语来开始搜索更多细节。评论不够清楚:bar()如果没有……将会是ambiguous@Nawaz:投票前仔细阅读评论。他说如果没有
::
,bar()
将会模棱两可。事实上,.@Cody:评论是在5分钟内编辑的。以前是“bar()将会模棱两可”,这显然是错误的!讽刺的是,原来的评论模棱两可!(这本身并没有错。即使考虑到最初的措辞,当前的解释也是完全合乎逻辑的。)@Cody:代码并不含糊,但评论说“bar()将是含糊不清的”.现在有什么困惑吗?谢谢,但我不明白,你写了-使用名称空间栏;为什么编译器不会从栏中使用foo?为什么在使用名称空间栏之后需要编写bar::foo;你能解释一下吗?“使用名称空间栏”意味着
foo()
本身就意味着
bar::foo()
。但是,可能您想在全局范围内使用
foo()
?也可以通过
foo()
访问它。因此
foo()
可以用于两者。现在编译器不确定您指的是哪一个,所以您必须指定。@EboMike“
foo()
本身意味着
bar::foo()
”太强。在查找
foo
的匹配项时,名称查找会考虑
bar::foo
(在本例中,会发现与
:foo
的歧义)