Подтвердить что ты не робот

Что происходит, когда класс и функция имеют одно и то же имя?

#include <iostream>
using namespace std;

struct test
{
    test(){cout<<"class"<<endl;}
};
void test(){cout<<"function"<<endl;}

int main()
{
    test();
    return 0;
}

Выход:

function  

(VS2013, gcc 4.8.1)

Почему функция выбрана? Разве это не двусмысленность?

4b9b3361

Ответ 1

Это называется скрытие имени и описано в

3.3 Область действия [basic.scope]

3.3.1 Декларативные области и области применения [basic.scope.declarative]

4) Учитывая набор объявлений в одном декларативном регионе, каждый из который указывает одно и то же неквалифицированное имя,
- все они будут ссылаться на один и тот же объект или все ссылаются на функции и шаблоны функций; или
- только одно объявление объявляет имя класса или перечисление имя, которое не является именем typedef, и другие объявления должны обратитесь к одной и той же переменной или перечислителю, или все относятся к функциям и шаблоны функций; в этом случае имя класса или перечисление имя скрыто (3.3.10). [...]

внимание мое.

Обратите внимание, что изменение порядка объявления не влияет на результат:

void test(){cout<<"function"<<endl;}

struct test
{
    test(){cout<<"class"<<endl;}
};

int main()
{
    test();
    return 0;
}

по-прежнему выводит function.

Если это не очевидно, не делать этого:)

Ответ 2

Из N3485 §3.3.10 [basic.scope.hiding]/2:

Имя класса (9.1) или имя перечисления (7.2) можно скрыть именем переменной, членом данных, функция или перечислитель, объявленный в той же области.

Следовательно, функция имеет приоритет над классом.

Как указано в комментариях, класс по-прежнему доступен с помощью ключевого слова class или struct. Если класс имел приоритет, функция была бы недоступна.

Ответ 3

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

Не поймите меня неправильно; Они верны и точны.

Я просто думаю, что это проще.

В вашем примере вы никогда не создаете экземпляр структуры.

Другими словами, вы его объявили, но вы никогда не использовали его.

Поскольку вы никогда не ссылались на него, он никогда не вызывается.

Приоритет имени и т.д. не применяются здесь, поскольку вы никогда не создавали структуру.

Надеюсь, что это поможет,

-Джон