Address of an overloaded function
Además de las expresiones de llamada a función , donde tiene lugar la resolución de sobrecarga , el nombre de una función sobrecargada puede aparecer en los siguientes 7 contextos:
| # | Contexto | Objetivo |
|---|---|---|
| 1 | inicializador en una declaración de un objeto o referencia | el objeto o referencia siendo inicializado |
| 2 | en el lado derecho de una expresión de asignación incorporada | el lado izquierdo de la asignación incorporada |
| 3 | como argumento de llamada a función | el parámetro de la función |
| 4 | como argumento de operador definido por el usuario | el parámetro del operador |
| 5 |
la sentencia
return
|
el valor de retorno de una función o conversión |
| 6 |
conversión explícita
o argumento de
static_cast
|
la conversión correspondiente |
| 7 | argumento de plantilla constante | el parámetro de plantilla correspondiente |
En cada contexto, el nombre de una función sobrecargada puede ir precedido por el operador de dirección
&
y puede estar encerrado en un conjunto redundante de paréntesis.
|
Si el tipo de destino contiene un tipo de marcador de posición , se realiza la deducción del tipo de marcador de posición, y la siguiente descripción utiliza el tipo deducido como tipo de destino. |
(since C++26) |
Contenidos |
Selección de funciones
Cuando se toma la dirección de una función sobrecargada, se selecciona un conjunto
S
de funciones del conjunto de sobrecarga referido por el nombre de la función sobrecargada:
- Si no hay un objetivo, se seleccionan todas las funciones no plantilla nombradas.
-
De lo contrario, una función no plantilla con tipo
Fse selecciona para el tipo de funciónFTdel tipo objetivo siF(después de aplicar posiblemente la conversión de puntero a función ) (desde C++17) es idéntico aFT. [1] -
La especialización (si existe) generada por la
deducción de argumentos de plantilla
para cada plantilla de función nombrada también se añade a
S.
Si el objetivo es de tipo puntero a función o referencia a tipo función,
S
solo puede incluir funciones no miembro
, funciones miembro de objeto explícito
(desde C++23)
y funciones miembro estáticas. Si el objetivo es de tipo puntero-a-función-miembro,
S
solo puede incluir funciones miembro de objeto implícito.
- ↑ En otras palabras, la clase de la cual la función es miembro se ignora si el tipo destino es un tipo puntero-a-función-miembro.
Eliminación de funciones
Después de formar el conjunto
S
, las funciones son eliminadas en el siguiente orden:
|
(desde C++20) |
-
Si más de una función en
Spermanece, todas las especializaciones de plantilla de función enSson eliminadas siStambién contiene una función no plantilla.
|
(desde C++20) |
-
Cualquier especialización de plantilla de función dada
spec
es eliminada si
Scontiene una segunda especialización de plantilla de función cuya plantilla de función está más especializada que la plantilla de función de spec .
Después de tales eliminaciones (si las hay), exactamente una función seleccionada debe permanecer en
S
. De lo contrario, el programa está mal formado.
Ejemplo
int f(int) { return 1; } int f(double) { return 2; } void g(int(&f1)(int), int(*f2)(double)) { f1(0); f2(0.0); } template<int(*F)(int)> struct Templ {}; struct Foo { int mf(int) { return 3; } int mf(double) { return 4; } }; struct Emp { void operator<<(int (*)(double)) {} }; int main() { // 1. inicialización int (*pf)(double) = f; // selecciona int f(double) int (&rf)(int) = f; // selecciona int f(int) int (Foo::*mpf)(int) = &Foo::mf; // selecciona int mf(int) // 2. asignación pf = nullptr; pf = &f; // selecciona int f(double) // 3. argumento de función g(f, f); // selecciona int f(int) para el 1er argumento // e int f(double) para el segundo // 4. operador definido por el usuario Emp{} << f; // selecciona int f(double) // 5. valor de retorno auto foo = []() -> int (*)(int) { return f; // selecciona int f(int) }; // 6. conversión auto p = static_cast<int(*)(int)>(f); // selecciona int f(int) // 7. argumento de plantilla Templ<f> t; // selecciona int f(int) // prevenir advertencias de "variable no utilizada" como si fuera [[maybe_unused]] [](...){}(pf, rf, mpf, foo, p, t); }
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| CWG 202 | C++98 |
el argumento de plantilla constante no era un contexto
para tomar la dirección de una función sobrecargada |
lo es |
| CWG 250 | C++98 |
las especializaciones de plantillas de función generadas con argumentos
de plantilla no deducidos no se seleccionaban del conjunto de sobrecarga |
también seleccionadas |
| CWG 1153 | C++98 | no estaba claro si un tipo de función dado coincide con el tipo objetivo | aclarado |
| CWG 1563 | C++11 |
no estaba claro si la inicialización de lista es un contexto
para tomar la dirección de una función sobrecargada |
aclarado |
Referencias
- Estándar C++23 (ISO/IEC 14882:2024):
-
- 12.3 Dirección de función sobrecargada [over.over]
- Estándar C++20 (ISO/IEC 14882:2020):
-
- 12.5 Dirección de función sobrecargada [over.over]
- Estándar C++17 (ISO/IEC 14882:2017):
-
- 16.4 Dirección de función sobrecargada [over.over]
- Estándar C++14 (ISO/IEC 14882:2014):
-
- 13.4 Dirección de función sobrecargada [over.over]
- Estándar C++11 (ISO/IEC 14882:2011):
-
- 13.4 Dirección de función sobrecargada [over.over]
- Estándar C++98 (ISO/IEC 14882:1998):
-
- 13.4 Dirección de función sobrecargada [over.over]