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

#include <iostream>
using namespace std;

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

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

выход:

function  

(VS2013 ang gcc 4.8.1)

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

3 ответов


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

3.3 область [basic.scope]

3.3.1 декларативные области и области [basic.масштаб.декларативный]

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.масштаб.прячась]/2:

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

таким образом, функция имеет приоритет над классом.

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


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

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

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

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

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

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

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

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

-Джон