Почему «идентификатор» считается неоднозначным с «identifier()», когда они используются по-разному?

#c

#c

Вопрос:

Это исключительно для примера, который я случайно заметил с!

Я использую cout with operator<< и почему эта программа не компилируется? Почему они не рассматриваются так, как перегрузки функций?

 #include <iostream> // imports the declaration of std::cout

using namespace std; // makes std::cout accessible as "cout"

int cout() // declares our own "cout" function
{
    return 5;
}

int main()
{
    cout << "Hello, world!"; // Compile error!

    return 0;
}
  

Комментарии:

1. Вот что using namespace std; означает: обрабатывайте все идентификаторы, определенные в std , как если бы они были определены в глобальном пространстве имен. Итак, когда вы добавляете другое определение cout в глобальное пространство имен, вы получаете конфликт. Краткий ответ: не пишите using namespace std; .

2. Why aren't they considered as function overloading when they're used differently? потому что std::cout это не функция.

3. Я прошу прощения за закрытие этого как дублирующего. Хотя вы задаете немного другой вопрос, я полагаю, что вы найдете ответ в этом сообщении.

4. @paddy — Я снова открыл вопрос, поскольку вы говорите, что закрыли его по ошибке.

5. Обратите внимание, что вполне возможно использовать имя объекта в круглых скобках и использовать имя функции без круглых скобок, поэтому компилятор не может отличить функцию от объекта с одинаковым именем на основе того, используются ли они в круглых скобках.

Ответ №1:

В момент попытки вставки потока в глобальной области видимости есть два имени cout : одно из стандартной библиотеки, std::cout перенесенное в глобальную область видимости этим адским using объявлением, и одно, определенное как функция int cout() . В выражении

 cout << "Hello, world!n";
  

использование cout неоднозначно. Перегрузки функции нет по двум причинам: во-первых, std::cout это не функция, поэтому она не принимала бы участия в перегрузке. Но что более важно, использование cout в этом выражении не является вызовом функции, поэтому, опять же, нет перегрузки. Имя cout из определения функции обрабатывается как указатель на функцию, а имя cout из пространства имен std — это имя объекта. Есть две возможные интерпретации этого имени, поэтому его использование в этом << выражении неоднозначно.

Комментарии:

1. Это хорошее объяснение. Но я не знаю, почему люди отклоняют мой вопрос. Если возможно, я хотел бы сохранить это для будущих читателей, которые запутались, как я.

2. @MichaelD.Blake Мое лучшее предположение заключается в том, что у многих пользователей SO есть неудачная привычка отклонять вопросы, если проблема частично связана с плохой практикой, т. Е. «если бы вы не сделали этого , вопрос не возник бы», хотя фактический предмет вопроса на самом деле не связан с плохой практикой. И хотя using namespace std; это не особенно хорошая идея, реальная плохая практика, например, «зачем вам вообще это делать?» — это присвоение имени функции cout . Но это всего лишь предположение, я не умею читать мысли.

3. @SebastianRedl Я знаю, что это плохая практика и все такое. Но я случайно заметил это с cout и сразу пришел сюда. Может быть, мне следует привести это в другом примере даже без какого-либо пространства имен?

4. @MichaelD.Blake Нет, ваш вопрос прекрасен, IMO. Я просто пытался объяснить, почему вы получаете отрицательные оценки. Иногда вам просто приходится с этим мириться. Ненавистники возненавидят.

5. @SebastianRedl Я согласен, но это сообщество, и если я не сделаю большинство счастливым, я не смогу ничего спросить.