unarios sobrecarga sencillos resueltos operadores metodos matrices funciones ejercicios ejemplos definicion c++ pass-by-reference pass-by-value function-overloading

c++ - sencillos - Sobrecarga de funciones basada en valor frente a referencia de const.



sobrecarga de operadores en c++ ejemplos sencillos (5)

¿Cómo podría la persona que llama diferenciar entre ellos?

No se puede diferenciar en este caso. Ambas funciones sobrecargadas tienen el mismo tipo de tipo de datos primitivos que el argumento. Y tomar por referencia no cuenta para un tipo diferente.

Hace declarar algo como lo siguiente

void foo(int x) { std::cout << "foo(int)" << std::endl; } void foo(const int &x) { std::cout << "foo(const int &)" << std::endl; }

alguna vez tiene sentido? ¿Cómo podría la persona que llama diferenciar entre ellos? He intentado

foo(9); // Compiler complains ambiguous call. int x = 9; foo(x); // Also ambiguous. const int &y = x; foo(y); // Also ambiguous.


El compilador no puede. Ambas definiciones de foo se pueden usar para todas las ''variantes'' de int.

En el primer foo, se hace una copia del int. Copiar un int siempre es posible.

En el segundo foo, se pasa una referencia a una constante. Dado que cualquier int puede convertirse en un const const, también se puede pasar una referencia al mismo.

Como ambas variantes son válidas en todos los casos, el compilador no puede elegir.

Las cosas se vuelven diferentes si, por ejemplo, utilizas la siguiente definición:

void foo (int &x);

Ahora llamarlo con foo(9) tomará la primera alternativa, ya que no puede pasar 9 como una referencia no constante.

Otro ejemplo, si reemplaza int por una clase en la que el constructor de copia es privado, el llamante no puede hacer una copia del valor y no se utilizará la primera variante foo.


La intención parece ser diferenciar entre invocaciones con temporarios (es decir, 9 ) y el paso de argumentos ''regulares''. El primer caso puede permitir que la implementación de la función emplee optimizaciones, ya que está claro que los argumentos se eliminarán posteriormente (lo cual no tiene ningún sentido para los literales enteros, pero puede tener sentido para los objetos definidos por el usuario).

Sin embargo, el estándar actual del lenguaje C ++ no ofrece una manera de sobrecargar específicamente para la ''valuación l / r'' de los argumentos: cualquier valor l que se pase como argumento a una función se puede convertir implícitamente en una referencia, por lo que la ambigüedad es inevitable.

C ++ 11 presenta una nueva herramienta para un propósito similar: al usar referencias de valor r , puede sobrecargarse de la siguiente manera

void foo(int x) { ... } void foo(const int &&x) { ... }

... y foo(4) (un valor r temporal, pasado como argumento) causaría que el compilador elija la segunda sobrecarga mientras que int i = 2; foo(i) int i = 2; foo(i) escogería el primero.

( nota : incluso con la nueva cadena de herramientas, no es posible diferenciar entre los casos 2 y 3 en su muestra)


No en C ++. Los lenguajes funcionales como Erlang y Haskell se acercan al permitirle especificar sobrecargas de funciones basadas en el valor del parámetro, pero la mayoría de los lenguajes imperativos, incluido C ++, requieren una sobrecarga basada en la firma del método; es decir, el número y el tipo de cada parámetro y el tipo del valor de retorno.

La palabra clave const en la firma define no el tipo de parámetro, sino su mutabilidad dentro de la función; un parámetro " const " generará un error de compilación si es modificado por la función o pasa por referencia a cualquier función que no use también const .


Podrías hacer esto con una plantilla:

template<typename T> void foo(T x) { ... }

Luego puede llamar a esta plantilla por valor o por referencia:

int x = 123; foo<int>(x); // by value foo<int const&>(x); // by refernce