Разрешение имен (name lookup, или поиск имени функции/переменной) это специальная фича языка программирования, при котором имя, встретившееся в программе, связывается с его декларацией.
Например, для компиляции std::cout << std::endl; компилятор выполняет следущие действия:
• unqualified name lookup (не квалифицированный поиск) для имени std, который найдет декларацию пространства имен std в заголовке < iostream> • qualified name lookup (квалифицированный поиск) для имени cout, который найдет декларацию переменной в пространстве имен std • qualified name lookup для имени endl, который найдет декларацию шаблона функции в пространстве имен std • зависимый от аргумента поиск (argument-dependent lookup) для имени оператора << который найдет несколько деклараций шаблонов функций в пространстве имен std, и одновременно qualified name lookup для имени std::ostream::operator<< , который найдет несколько деклараций функций-членов класса std::ostream.
Для имен функций и шаблонов функций name lookup может связать несколько деклараций с одинаковым именем, и может получить дополнительные декларации из argument-dependent lookup. Может также применяться дедукция аргумента шаблона функции [6], и набор деклараций передется в разрешение перегрузки (overload resolution), которое выберет конкретную декларацию, которая будет использоваться. Правила доступа к членам класса, если они применимы, учитываются только после name lookup и overload resolution.
Для всех других имен (переменных, пространств имен, классов и т. д.), name lookup должно предоствить одину декларацию, чтобы программа могла скомпилироваться. Поиск имени в области находит все декларации этого имени, с одним исключением, известным как "struct hack" или "type/non-type hiding": в одной и той же области некоторые появления имени могут относиться к декларации class/struct/union/enum, которые не являются typedef, в то время как все другие появления того же имени либо все относятся к одной переменной, нестатическому члену класса (начиная со стандарта C++14), или перечислителю, или все они возможно относятся к именам перегружаемой функции или шаблона функции. В этом случае, если не было ошибки, оба имени типа скрываются от поиска (код должен использовать уточненный спецификатор доступа к ним).
[Типы поиска]
Если имя появляется немедленно справа от оператора разрешения области действия :: или возможно после :: с последующим устранаяющим неоднозначачность ключевым словом template, см. квалифицированный поиск имени [2], иначе см. не квалифицированный поиск имени [3]. Последний для имен функций включает в себя поиск с использованием аргументов функции [4].
[Ссылки]
1. Name lookup site:cppreference.com. 2. Qualified name lookup site:cppreference.com. 3. Unqualified name lookup site:cppreference.com. 4. Argument-dependent lookup site:cppreference.com. 5. Scope site:cppreference.com. 6. Function template site:cppreference.com. 7. Overload resolution site:cppreference.com. |