Búsqueda de nombre
Búsqueda de nombre, cuando el programa aparece en un nombre cuando es con la introducción de su 声明
proceso de vinculación
Por ejemplo, para compilar std :: cout << std :: endl;, el compilador realiza:
- La búsqueda de nombre no calificado del nombre std encontró la declaración del espacio de nombres std en el archivo de encabezado
- Una búsqueda de nombre calificado para el nombre cout encontró una declaración de variable en el espacio de nombres std
- Una búsqueda de nombre calificado para el nombre endl encontró una declaración de plantilla de función en el espacio de nombres std
- El operador de nombre <<
实参依赖查找
encontró varias declaraciones de plantilla de función en el espacio de nombres std; ystd::ostream::operator<<
la búsqueda de nombre calificado del nombre encontróstd::ostream
varias declaraciones de función miembro en la clase
Para nombres en funciones y plantillas de funciones, la búsqueda de nombres puede asociar el mismo nombre con varias declaraciones y puede obtener declaraciones adicionales de la búsqueda de dependencias de argumentos . También realizará la deducción del argumento de la plantilla y dará el conjunto de declaraciones a la resolución de sobrecarga , que elegirá la declaración que se utilizará. 成员访问
Las reglas de solo se considerarán después de la búsqueda de nombres y la resolución de sobrecargas, si corresponde
- Para la búsqueda de nombres de todos los demás nombres (variables, espacios de nombres, clases, etc.), el programa solo se puede compilar si solo se genera una declaración.
- La búsqueda de un nombre en un alcance encontrará todas las declaraciones de ese nombre, pero hay una excepción, que se llama "struct hack" o "ocultación de nombre de tipo / no tipo":
- En el mismo ámbito, algunas apariciones de un nombre pueden representar declaraciones de clase / estructura / unión / enumeración que no son typedef,
- Las otras apariciones representan todas la misma variable, miembro de datos no estáticos (desde C ++ 14) o enumeración, o todas representan el nombre de una función o plantilla de función que puede estar sobrecargada.
- No hay ningún error en este caso, pero el nombre del tipo está oculto en la búsqueda (el código debe usar el especificador de tipo detallado para acceder a él).
Tipo de búsqueda
Búsqueda de nombre calificado
El nombre que aparece a la derecha del operador de resolución de alcance :: es el nombre calificado (consulte Identificadores calificados). El nombre calificado puede representar:
- Los miembros de la clase (incluidas funciones, tipos, plantillas, etc. estáticas y no estáticas)
- Miembros del espacio de nombres (incluidos otros espacios de nombres)
- Enumeración
Si el ::
lado izquierdo está vacío, el proceso de búsqueda solo considerará las declaraciones realizadas en el ámbito del espacio de nombres global (o introducidas en el espacio de nombres global a través de una declaración de uso) . Esto permite que incluso los nombres ocultos por declaraciones locales sean accesibles:
#include <iostream>
int main() {
struct std{
};
std::cout << "fail\n"; // 错误:对 'std' 的无限定查找找到 struct
::std::cout << "ok\n"; // 正确: ::std 找到命名空间 std
}
Solo después de completar la búsqueda del nombre a la izquierda de :: (a menos que la expresión decltype se use a la izquierda o la izquierda esté vacía), se puede buscar el nombre de la derecha.
struct A {
static int n;
};
int main() {
int A;
A::n = 42; // 正确:对 :: 左边的 A 的无限定查找忽略变量
A b; // 错误:对 A 的无限定查找找到了变量 A
}
Identificador calificado
Una expresión de identificación calificada está precedida por una expresión de identificación no calificada con un operador de resolución de alcance :: y, opcionalmente, una serie de enumeraciones separadas por operadores de resolución de alcance, (desde C ++ 11) El nombre de la clase o espacio de nombres, o expresión decltype ( desde C ++ 11)
- La expresión std :: string :: npos es la expresión del miembro estático npos en la cadena de clase nombrada en el espacio de nombres std
- La expresión ·
::tolower
nombra la función tolower en el espacio de nombres global - La expresión se
::std::cout
refiere a la variable global cout en el espacio de nombres estándar (espacio de nombres de nivel superior)