Function overload in C ++ passing arguments by value or by reference (Function Overloading)

2

Assuming we have this example of functions in C ++

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

Is there a possibility to differentiate which function I want to invoke by making some modification in the call arguments?

If the foo function is invoked in any of these modes:

foo( 10);

i = 10;
foo( static_cast<const int>(i));

foo( static_cast<const int&>(i)); // Aunque aquí convertir un tipo básico a través de una referencia no tiene mucha utilidad. Sólo es para exponer los casos posibles.

Invokes the first of the two overloaded functions, because a constant argument can not be passed to a non-constant parameter. But how would it be done to invoke the second of the overloaded functions? If I make the following invocation:

int i = 10;
foo( i);

An ambiguity error occurs because both functions are valid for this argument.

In this link link exposes that a way to solve it is, in the case of handling objects instead of basic types , make the copy constructor private so that, since it can not make a copy of the value, it must obligatorily invoke the second function and pass the object by reference. But what about the basic types? Do you have to change the name of the functions to avoid this kind of problems?

    
asked by Carlos A. Gómez 15.08.2016 в 13:26
source

1 answer

2
int i = 10;
foo( i);
     

An ambiguity error occurs because both functions are valid for this argument.

That's right, C ++ NO has no mechanism to distinguish between the call by copy and the call by reference, so the answers to and the basic types exist somehow? It would be a simple no.

But it is a very boring answer, so we will try to use language tools to try to fulfill the objective:

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

We can modify the behavior and skip the ambiguity using the unary operator + :

int i = 10;
foo(+i); // Llamada no ambigua: llama foo(int)

Applying the unary operator + on a type returns its value, so the only option available is the call to foo per copy (goodbye ambiguity!) ... unfortunately this does not solve the call to the non-constant reference version.

The only way to achieve this is to make one of the two options better than the other in case of ambiguity, for example by making one of the functions a template:

template <typename T>
void foo(T x)  { std::cout   << "foo(int)"   << std::endl; }
void foo(int& x) { std::cout << "foo(int &)" << std::endl; }

int i = 10;
foo(i);  // Llamada no ambigua: foo(int&) es la mejor opcion
foo(10); // Llamada no ambigua: foo(T) es la mejor opcion

When the compiler chooses between a template version and a non-template version, the non-template is a better option, so the ambiguity ends; unfortunately the latter option implies that " Mandatory change the name to the functions to avoid this type of problems ", meaning "name of the functions" by the type of the same.

    
answered by 16.08.2016 / 09:41
source