¿Se tratan los objetos de funciones de forma diferente a las funciones normales durante la resolución de sobrecarga? ¿Si es así, cómo?¿Cómo afectan los objetos a la resolución de sobrecarga?
he ejecutar en el siguiente caso en el que la sustitución de una función con un objeto de función equivalente-exigible cambió el significado del código:
#include <iostream>
namespace N
{
enum E { A, B };
void bar(E mode) { std::cout << "N::bar\n"; }
}
template <typename... Args>
void bar(Args&&... args) { std::cout << "global bar\n"; }
int main()
{
bar(N::A);
}
Aquí la salida es "N :: bar". Hasta ahora, todo bien: ND bar está siendo encontrado por ADL, tanto N :: bar como la barra global son coincidencias exactas, y se prefiere N :: bar porque no es una plantilla.
Pero si cambio de la barra global para ser un objeto de función, así:
#include <iostream>
namespace N
{
enum E { A, B };
void bar(E mode) { std::cout << "N::bar\n"; }
}
struct S
{
template <typename... Args>
void operator()(Args&&... args) { std::cout << "global bar\n"; }
};
S bar;
int main()
{
bar(N::A);
}
La salida es ahora "global bar". ¿Por qué la diferencia?
Hoy aprendí, gracias David. – ildjarn
No creo que la nota en 3.4.1/3 es relevante, porque 'bar' * es * la expresión de postfijo en una expresión de llamada a función (¡que no tiene una función como operando, pero finalmente llama a uno!). La nota dice que 3.4.2 no cambia el significado sintáctico de "x (y)" - si se trata de una llamada a función, se mantiene como una llamada de función sin tener en cuenta lo que 3.4.2 decide hacer. –
@ JohannesSchaub-litb: la búsqueda regular encontrará que 'bar' es un objeto, y al ser un objeto' bar (x) 'representa la aplicación de' operator() 'a esa instancia. Mientras que la aplicación del operador es una llamada a función, es una llamada a * member-function * y, por lo tanto, ADL no se aplica. –