Что означает "::" в ":: tolower"? - PullRequest
11 голосов
/ 11 марта 2011

Я видел такой код:

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

И у меня есть вопрос: что означает :: до tolower?

и std::tolower не работает, но ::tolower работает нормально

Ответы [ 4 ]

10 голосов
/ 11 марта 2011

Почему :: необходим: стандарт определяет два tolower, шаблон функции в std:: и простая функция в :: и std::. В зависимости от того, какие заголовки были включены (и это включает Заголовки косвенно включены из других заголовков, которые вы можете не знать о), либо одно, либо другое, либо оба могут быть видны. Использование :: обеспечивает что используется более старый из стандарта C. (Если один в std:: считается, что вызов будет неоднозначным, так как преобразование является шаблоном сам, и компилятор не сможет вывести шаблон аргументы.)

Пока я в этом, я мог бы упомянуть, что использование ::tolower, как это неопределенное поведение, по крайней мере, если обычный символ подписан. Вход в ::tolower является целым числом и должно находиться в диапазоне 0 ... UCHAR_MAX или EOF. Если простой символ подписан, некоторые символы могут иметь отрицательный кодировки, что приводит к неопределенному поведению. На практике большинство реализации делают эту работу. Для всех символов, кроме 0xFF (ÿ в Латынь 1). Если вас не интересует переносимость, некоторые компиляторы переключатель, чтобы сделать символ без знака --- используйте его. В противном случае напишите небольшой функциональный объект для правильной обработки, либо:

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

или (лучше, но значительно больше работы --- только стоит, если вы используете его много), функциональный объект, чей конструктор принимает локаль (по умолчанию к глобальной локали) и содержит ссылку на std::ctype, который он использует для функции tolower. (Конечно, если вы действительно интернационализированный, tolower, вероятно, не имеет никакого значения. А также вы будете использовать UTF-8, который является многобайтовой кодировкой и не работает с любой из доступных возможностей.)

8 голосов
/ 11 марта 2011

Означает, что он явно использует 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()
}
4 голосов
/ 11 марта 2011

Использовать версию из глобального пространства имен.(Возможно <ctypes.h>, а не <cctypes>, если std:: не работает)

0 голосов
/ 11 марта 2011

:: это глобальное пространство имен.

#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 ::
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...