1

I'm having a problem with using C++ overloading and was wondering if anybody could help.

I'm trying to overload functions so that its argument accept reference and literal respectively.

For example, I want to overload func1 and func2 to func:

int func1 (int literal); 
int func2 (int &reference);

and I want to use func in this situations:

func(3);   // call func1
int val = 3;
func(val); // I want func2 to be called, but ambiguous error

Is there any way to overload these functions?

thanks! Any help would be appreciated! sorry for poor english.

WON
  • 83
  • 1
  • 9
  • 1
    `const int &literal` and `int &reference`? – Goswin von Brederlow May 27 '22 at 01:09
  • @GoswinvonBrederlow thanks for comments, but I want to update the variable ```reference``` in ```func2``` (so it could not be ```const int&```) – WON May 27 '22 at 01:12
  • 3
    It is strange to want this overload. Typically you want overloads to perform similar tasks for a several different type of arguments. But in your case it seems like the overloads do very different things. One tries to modify the argument and the other can't so they can't do similar things. – François Andrieux May 27 '22 at 01:15
  • 1
    @won But the reference should take the second case. Literals and temporaries must take the `const` case. If not then my suggestion fails. – Goswin von Brederlow May 27 '22 at 01:17
  • Yes. It’s called a template. That being said, this is clearly an xy problem. – Taekahn May 27 '22 at 01:19
  • Using move semantic might make move sense than modifying. – Goswin von Brederlow May 27 '22 at 01:24
  • I'm really sorry for the confusion. I misunderstood ```const int& literal``` for ```const int& refernece```. Goswin's method works. – WON May 27 '22 at 01:37
  • Not sure you can do what you are trying to do, but surely it's a wrong path. You are putting yourself in a scenario where compliler is not able to disambiguate. Even if you can get rid of it somehow, you are just complicating code for the ones that will have to read it next time. "Which funcion am I calling here?" What about `funcByVal (int someVal)` and `funcByRef(int& someRef)`? Compiler is your friend, don't overuse it and make it an enemy – Gian Paolo May 27 '22 at 18:14

1 Answers1

0

Literals and temporary values can only be passed as const references while named values will prefer a non-const reference if available. You can use this with either & or && to create the 2 overloads.

For why and more details read up on rvalues, lvalues, xvalues, glvalues and prvalues.

The code below shows which function overload will be used for the most common cases, the first 2 being the ones you asked about:

#include <iostream>

void foo1(int &) { std::cout << "int &\n"; }
void foo1(const int &) { std::cout << "const int &\n"; }

void foo2(int &) { std::cout << "int &\n"; }
void foo2(const int &) { std::cout << "const int &\n"; }
void foo2(int &&) { std::cout << "int &&\n"; }
void foo2(const int &&) { std::cout << "const int &&\n"; }

int bla() { return 1; }

int main() {
    int x{}, y{};
    std::cout << "foo1:\n";
    foo1(1);
    foo1(x);
    foo1(std::move(x));
    foo1(bla());
    std::cout << "\nfoo2:\n";
    foo2(1);
    foo2(y);
    foo2(std::move(y));
    foo2(bla());
}

Output:

foo1:
const int &
int &
const int &
const int &

foo2:
int &&
int &
int &&
int &&
Goswin von Brederlow
  • 11,875
  • 2
  • 24
  • 42
  • 1
    This doesn't answer the question... The output is clearly wrong. – Qix - MONICA WAS MISTREATED May 27 '22 at 01:34
  • 1
    It's shows one function getting called for `foo(1)` and another for `foo(x)`, which was the question. – Goswin von Brederlow May 27 '22 at 01:46
  • The literal shares overloads with two others. It is only the actual lvalue overload that is different, which is not what the OP asked for as I understand it. – Qix - MONICA WAS MISTREATED May 27 '22 at 01:48
  • 1
    @Qix-MONICAWASMISTREATED The question asks for `func(3)` and `func(val)`. That's the first 2 cases each. I just included the other 2 cases to show what other cases do. I think having one function for names values and one for everything else is the best you can do with function overload. – Goswin von Brederlow May 27 '22 at 01:51
  • This answer seems incomplete. Please include a description of how this answers the question, which can then be supported by the code, instead of just showing code and assuming that the intent is clear enough. I'm also confused about why you have `foo1` and `foo2` and about which of these solutions you are actually recommending, and why. – François Andrieux May 27 '22 at 10:49