tipos programas lenguaje funciones ejemplos dev datos comandos codigos basicos c++ c++11 overloading method-overloading ampersand

c++ - programas - lenguaje c



Sobrecarga de la funciĆ³n miembro de C++ con &(ampersand) (5)

¿Cómo elegir la función de miembro error () correcta? ¿Necesito lanzar de alguna manera?

using namespace std; struct test { int error(); void error(int x); int fun(); }; int main() { auto f1 = &test::error; // how to pick the correct function? auto f2 = &test::fun; // works }


¿Necesito lanzar de alguna manera?

Sí, puedes usar static_cast .

static_cast también se puede usar para desambiguar las sobrecargas de funciones realizando una conversión de función a puntero a un tipo específico, como en

std::transform(s.begin(), s.end(), s.begin(), static_cast<int(*)(int)>(std::toupper));

Así que puedes:

auto f1 = static_cast<int(test::*)()>(&test::error); auto f2 = static_cast<void(test::*)(int)>(&test::error);


Aquí está la solución cuando no tiene internet para leer la sintaxis fea de puntero a miembro de función:

auto err1 = [](test& t) { return t.error(); }; auto err2 = [](test& t, int x) { return t.error(x); };

Tenga en cuenta que hasta ahora obtiene los cierres como tipos y no como punteros de función. Si quería punteros de función, lo que es útil si desea almacenar diferentes funciones miembro con la misma firma en una matriz, puede convertir el cierre en un puntero de función (normal) a través de + (consulte here ).

Por lo que puedo ver en este momento, con lo anterior puede hacer conceptualmente cualquier cosa que pueda hacer con punteros de función a miembro, excepto, por supuesto, llamar a una rutina que exija exactamente ese puntero. Y es mucho mejor.


Como ya se ha dado una respuesta, presentaré una solución que es más fácil para los ojos. Esta situación es perfecta para una macro si no desea escribir el reparto cada vez:

template<class T> using test_type_t = T test::*; #define TEST_CAST(T, F) static_cast<test_type_t<T>>(&F) auto f1 = TEST_CAST(void(int), test::error);


Puede especificar explícitamente el tipo de puntero de función miembro.

int (test::*f1)() = &test::error; void (test::*f2)(int) = &test::error;


Tendrá que usar un static_cast para desambiguar.

&test::error no es evaluable ya que la función está sobrecargada. El hecho de que esté asignando esto a algo marcado como auto no es relevante de inmediato.

Una solución sería utilizar static_cast<int(test::*)()>(&test::error) o static_cast<void(test::*)(int)>(&test::error) según corresponda.

Entonces, el auto funcionará ya que no habrá ambigüedad en la deducción de tipo.