Что происходит, когда класс и функция имеют одно и то же имя?
#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)
Почему функция выбрана? Разве это не двусмысленность?
3 ответа
Это называется скрытием имени и описано в
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
,
Если это не очевидно, не делайте этого:)
Из N3485 §3.3.10 [basic.scope.hiding]/2:
Имя класса (9.1) или имя перечисления (7.2) может быть скрыто по имени переменной, члена данных, функции или перечислителя, объявленных в той же области.
Следовательно, функция имеет приоритет над классом.
Как уже упоминалось в комментариях, класс все еще доступен через class
или же struct
ключевое слово. Если бы класс имел приоритет, функция была бы недоступна.
Я не уверен, что любой из предыдущих ответов является "почему" для вашего конкретного случая.
Не пойми меня неправильно; Они правдивы и точны.
Я просто думаю, что это проще.
В вашем примере вы никогда не создаете экземпляр структуры.
Другими словами, вы объявили это, но никогда не использовали это.
Поскольку вы никогда не ссылались на него, он никогда не называется.
Приоритет имени и тому подобное здесь не применяются, так как вы никогда не создавали экземпляр структуры.
Надеюсь это поможет,
-John