Leí algunas preguntas aquí sobre SO sobre este tema que me parece confuso. Recién comencé a aprender C ++ y aún no he estudiado las plantillas o la sobrecarga de operadores y demás.
Ahora, ¿hay una forma sencilla de sobrecargar
class My {
public:
int get(int);
char get(int);
}
sin plantillas o comportamiento extraño? o debería simplemente
class My {
public:
int get_int(int);
char get_char(int);
}
?
c++
overloading
Zapato
fuente
fuente

intvalor de retorno se verá así(int)get(9)y concharesto(char)get(9).Respuestas:
No, no lo hay. No puede sobrecargar métodos basados en el tipo de retorno.
La resolución de sobrecarga tiene en cuenta la firma de la función . Una firma de función se compone de:
Y aquí está la cita:
1.3.11 firma
Opciones:
1) cambie el nombre del método:
class My { public: int getInt(int); char getChar(int); };2) parámetro de salida:
class My { public: void get(int, int&); void get(int, char&); }3) plantillas ... exagerado en este caso.
fuente
My::get<T>(int). Es una alternativa válida _ si 1) tienes que manejar muchos tipos diferentes, todos con el mismo código básico (por ejemploboost::lexical_cast<T>( someStringValue ), o tienes que poder llamar a estas funciones desde alguna otra plantilla (myMy.get<T>( i ), dondeThay un argumento de esta otra plantilla . De lo contrario, como dice Luchian, son exagerados.my.get(0);al compilador, no tendría forma de decidir qué pieza de código ejecutar.void foo(int x = 0) {} void foo(double x = 0) {}debería ser rechazado. Sin embargo, no lo es. Solo en el caso de que el compilador realmente no pueda distinguir (foo()) obtendrá un errorEs posible, pero no estoy seguro de que sea una técnica que recomendaría a los principiantes. Como en otros casos, cuando desea que la elección de funciones dependa de cómo se usa el valor de retorno, usa un proxy; primero defina funciones como
getCharygetInt, luego un genéricoget()que devuelve un Proxy como este:class Proxy { My const* myOwner; public: Proxy( My const* owner ) : myOwner( owner ) {} operator int() const { return myOwner->getInt(); } operator char() const { return myOwner->getChar(); } };Extiéndalo a tantos tipos como necesite.
fuente
std::string, y el proxy solo lo ofreceoperator char const*(), no funcionará.No, no puede sobrecargar por tipo de retorno; solo por tipos de parámetros y calificadores const / volatile.
Una alternativa sería "regresar" usando un argumento de referencia:
void get(int, int&); void get(int, char&);aunque probablemente usaría una plantilla o funciones con nombres diferentes como su segundo ejemplo.
fuente
intcódigo de error.Puedes pensar de esta manera:
Tienes:
int get(int); char get(int);Y no es obligatorio recopilar el valor de retorno de la función al invocar.
Ahora, invocas
get(10); -> there is an ambiguity here which function to invoke.Por lo tanto, no tiene sentido si se permite la sobrecarga según el tipo de retorno.
fuente
Resucitando un hilo antiguo, pero puedo ver que nadie mencionó la sobrecarga de los calificadores de referencia. Los calificadores de referencia son una característica del lenguaje agregada en C ++ 11 y recientemente me encontré con ella; no está tan extendida como, por ejemplo, los calificadores de cv. La idea principal es distinguir entre los dos casos: cuando la función miembro se llama en un objeto rvalue y cuando se llama en un objeto lvalue. Básicamente, puedes escribir algo como esto (estoy modificando ligeramente el código de OP):
#include <stdio.h> class My { public: int get(int) & { // notice & printf("returning int..\n"); return 42; } char get(int) && { // notice && printf("returning char..\n"); return 'x'; }; }; int main() { My oh_my; oh_my.get(13); // 'oh_my' is an lvalue My().get(13); // 'My()' is a temporary, i.e. an rvalue }Este código producirá el siguiente resultado:
returning int.. returning char..Por supuesto, como es el caso de los calificadores cv, ambas funciones podrían haber devuelto el mismo tipo y la sobrecarga aún sería exitosa.
fuente
Como se dijo antes, las plantillas son exageradas en este caso, pero sigue siendo una opción que vale la pena mencionar.
class My { public: template<typename T> T get(int); }; template<> int My::get<int>(int); template<> char My::get<char>(int);fuente
Si bien la mayoría de los otros comentarios sobre este problema son técnicamente correctos, puede sobrecargar efectivamente el valor de retorno si lo combina con el parámetro de entrada de sobrecarga. Por ejemplo:
class My { public: int get(int); char get(unsigned int); };MANIFESTACIÓN:
#include <stdio.h> class My { public: int get( int x) { return 'I'; }; char get(unsinged int x) { return 'C'; }; }; int main() { int i; My test; printf( "%c\n", test.get( i) ); printf( "%c\n", test.get((unsigned int) i) ); }El resultado de esto es:
fuente
No hay forma de sobrecargar por tipo de retorno en C ++. Sin usar plantillas, usar
get_intyget_charserá lo mejor que pueda hacer.fuente
template <class T> T get(int)funcionaría?get<int>oget<char>, lo que realmente no te hace ganar muchoget_intyget_charsi no estás usando también otras funciones de plantilla.Tsi tiene algo comoT get(T). Si llamaget('a'), el compilador deduce queTes unchary no tiene que llamar explícitamenteget<char>('a'). Todavía no estoy seguro de si esto es estándar, aunque creo que lo es. Para su información, tanto GCC como Clang lo admiten.Tcualquier otro lugar, incluido el tipo de retorno. Esperaba que dieras un ejemplo del compilador deduciendoTde la función en el primer comentario de Niklas.No puede sobrecargar métodos basados en tipos de devolución. Su mejor opción es crear dos funciones con una sintaxis ligeramente diferente, como en su segundo fragmento de código.
fuente
no se puede sobrecargar una función en función del tipo de retorno de la función. puede sobrepasar según el tipo y la cantidad de argumentos que toma esta función.
fuente
Usé la respuesta de James Kanze usando un proxy:
https://stackoverflow.com/a/9569120/262458
Quería evitar usar muchos static_casts feos en un void *, así que hice esto:
#include <SDL_joystick.h> #include <SDL_gamecontroller.h> struct JoyDev { private: union { SDL_GameController* dev_gc = nullptr; SDL_Joystick* dev_js; }; public: operator SDL_GameController*&() { return dev_gc; } operator SDL_Joystick*&() { return dev_js; } SDL_GameController*& operator=(SDL_GameController* p) { dev_gc = p; return dev_gc; } SDL_Joystick*& operator=(SDL_Joystick* p) { dev_js = p; return dev_js; } }; struct JoyState { public: JoyDev dev; }; int main(int argc, char** argv) { JoyState js; js.dev = SDL_JoystickOpen(0); js.dev = SDL_GameControllerOpen(0); SDL_GameControllerRumble(js.dev, 0xFFFF, 0xFFFF, 300); return 0; }¡Funciona perfectamente!
fuente