Is it not possible to overload functions based on rvalue reference.

Hi,

I am just wondering why the following code gives ambiguous overload error?


error: call of overloaded ‘fn(B)’ is ambiguous fn(B{});



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class B {
  public:
    int x;
};

void fn(B&& b) {    //[x]
  return;
}

void fn(B b) {     //[y]
  return;
}

int main() {
  B b;
  fn(B{});    //[1]
  fn(b);      //[2]
  return 0;
}


a) Why does code works fine when we comment [1] ?

b) How does [2] get resolved but [1] gives error, shouldn't it be that if [1]
gives ambiguous overload error, [2] also should give ambiguous overload
error.

c) [1] passes a r-value then why [x] and [y] are ambiguous, isn't [x] a
perfect match for fn. call at [1], why is it not resolved.

Thanks alot for any inputs :)
Last edited on
I guess you are under the impression that [y] would only bind lvalues, but this is not the case. If you want to select between lvalues and rvalues, you would overload for (generally const) lvalue references and (generally non-const) rvalue references:

1
2
3
4
5
6
7
8
9
void fn(B&& b) {    //[x]
  // later: move from the lvalue b, bound to some rvalue:
  // use(std::move(b));
}

void fn(B const &b) {//[y]
  // later: 
  // use(b);
}


Probably you wouldn't be surprised by the ambiguity here:
1
2
3
4
5
int f(int &i); // [ a ]
int f(int i); // [ b ]
// ...
int i = 24; 
f(i);

This is ambiguous because i can either be bound to the lvalue reference in [ a ] or copied to initialize the parameter in [ b ].

Similarly, given
1
2
3
4
int g(int &&i); // [ c ]
int g(int i); // [ d ]
// ...
g(24);

The prvalue 24 can either be bound to the rvalue reference parameter in [ c ] or used to construct the int in [ d ].
Last edited on
Thanks mbozzi. I was under wrong impression. :/
Topic archived. No new replies allowed.