“::”是什么意思? “::tolower”是什么意思?

发布于 2024-10-21 13:37:54 字数 275 浏览 2 评论 0原文

我见过这样的代码:

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

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

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

I've seen code like this:

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

And I have a question: what does mean :: before tolower?

and std::tolower not works, but ::tolower works OK

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

残疾 2024-10-28 13:37:54

至于为什么 :: 是必要的:标准定义了两个 tolower
std:: 中的函数模板,以及 :::: 中的简单函数
std::。取决于已包含哪些标头(其中包括
从其他标头间接包含的标头,您可能不知道
关于),其中之一、另一个或两者都可能是可见的。使用 :: 确保
使用来自 C 标准的旧版本。 (如果 std:: 中的那个
被认为,调用将是不明确的,因为转换是一个模板
本身,编译器将无法推导出模板

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

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

或者(更好,但显着更多的工作——只有当你使用它时才值得
很多),一个函数对象,其构造函数采用语言环境(默认
到全局语言环境)并包含对 std::ctype 的引用,其中
它用于 tolower 函数。 (当然,如果你真的
国际化后,tolower可能没有任何意义。和
您将使用 UTF-8,这是一种多字节编码,并且不起作用
与任何可用的可能性。)

As to why the :: is necessary: the standard defines two tolower's,
a function template in std::, and a simple function in both :: and
std::. Depending on which headers have been included (and that includes
headers indirectly included from other headers, which you may not know
about), either one, the other, or both may be visible. Using :: ensures
that the older one, from the C standard, is used. (If the one in std::
is considered, the call will be ambiguous, since transform is a template
itself, and the compiler will not be able to deduce the template
arguments.)

While I'm at it, I might mention that using ::tolower like this is
undefined behavior, at least if plain char is signed. The input to
::tolower is an int, and must be in the range 0...UCHAR_MAX, or EOF. If
plain char is signed, some of the characters may have negative
encodings, which results in undefined behavior. In practice, most
implementations make this work. For all characters except 0xFF (ÿ in
Latin 1). If you're not concerned with portability, some compilers have
a switch to make char unsigned---use it. Otherwise, write a small
functional object to handle it correctly, either:

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

or (better, but significantly more work---only worth it if your using it
a lot), a functional object whose constructor takes a locale (defaulting
to the global locale) and contains a reference to an std::ctype, which
it uses for the tolower function. (Of course, if you're really
internationalized, tolower probably doesn't have any meaning. And
you'll be using UTF-8, which is a multi-byte encoding, and doesn't work
with any of the available possibilities.)

梦太阳 2024-10-28 13:37:54

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

例子:

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()
}

Means that it is explicitly using the tolower in the global namespace (which is presumably the stdc lib one).

Example:

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()
}
丑疤怪 2024-10-28 13:37:54

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

Use the version from the global namespace. (Probably included <ctypes.h> and not <cctypes> if std:: doesn't work)

别再吹冷风 2024-10-28 13:37:54

:: 是全局命名空间。

#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 ::
}

:: is the global namespace.

#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 ::
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文