Я видел такой код:
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
в глобальном пространстве имен (которое предположительно является пространством 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()
}
foo()
само по себе подразумевает bar::foo()
. Однако, может быть, вы хотели использовать foo()
в глобальной области видимости? К этому также можно получить доступ через foo()
. Таким образом, foo()
можно использовать для обоих. Теперь компилятор не уверен, какой из них вы имели в виду, поэтому вам нужно указать.
- person EboMike; 11.03.2011
foo()
сам по себе подразумевает, что bar::foo()
слишком сильный. Поиск имени учитывает bar::foo
при поиске соответствия для foo
(и в этом случае находит двусмысленность с ::foo
)
- person Caleth; 12.07.2018
Что касается того, почему ::
необходим: стандарт определяет два tolower
, шаблон функции в std::
и простую функцию как в ::
, так и в std::
. В зависимости от того, какие заголовки были включены (включая заголовки, косвенно включенные из других заголовков, о которых вы можете не знать), может быть виден один, другой или оба. Использование ::
гарантирует, что будет использован более старый из стандарта C. (Если рассматривать тот, что в std::
, вызов будет неоднозначным, так как transform сам по себе является шаблоном, и компилятор не сможет вывести аргументы шаблона.)
Пока я на этом, я мог бы упомянуть, что использование ::tolower
подобным образом является неопределенным поведением, по крайней мере, если подписан обычный символ. Входные данные для ::tolower
являются целыми и должны находиться в диапазоне 0
...UCHAR_MAX
или EOF
. Если подписан обычный символ, некоторые символы могут иметь отрицательное кодирование, что приводит к неопределенному поведению. На практике в большинстве реализаций это работает. Для всех символов, кроме 0xFF
(ÿ на латинице 1). Если вас не волнует переносимость, в некоторых компиляторах есть переключатель, делающий char беззнаковым --- используйте его. В противном случае напишите небольшой функциональный объект для правильной обработки:
struct ToLower
{
char operator()( char ch ) const
{
return ::tolower( static_cast<unsigned char>(ch) );
}
};
или (лучше, но значительно больше работы — стоит того, только если вы его часто используете), функциональный объект, конструктор которого принимает локаль (по умолчанию глобальная локаль) и содержит ссылку на std::ctype
, который он использует для tolower
функция. (Конечно, если вы действительно интернационализированы, tolower
, вероятно, не имеет никакого значения. И вы будете использовать UTF-8, которая является многобайтовой кодировкой и не работает ни с одной из доступных возможностей. )
Используйте версию из глобального пространства имен. (Возможно, включен <ctypes.h>
, а не <cctypes>
, если std::
не работает)
<locale>
(я сказал «потенциальная», потому что не знаю, насколько совместим VC++6 в этом вопросе... зачем использовать такой старый компилятор?)
- person AProgrammer; 11.03.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 ::
}
::bar()
было бы двусмысленно без ::
. На самом деле да.
- person Cody Gray; 11.03.2011
bar()
, которую он имел в виду, будет двусмысленной. В первый раз, когда я прочитал это, я правильно истолковал это, но я мог видеть, как вы предполагали что-то совершенно другое.
- person Cody Gray; 11.03.2011