Overloading on rvalue and lvalue references
// Overloading on lvalue/rvalue references
I am just starting to come to grips with rvalue references and how
they may be applied in several of the expected 'conventional' uses.
However, in some cases I find I have doubts based on an uncertainty
as to how well my compiler (gcc-4.3.2, Cygwin) actually implements
the current C++0x proposals for rvalue refs (or, for that matter,
how well I understand what I think I understand!).
To begin grounding my understanding, one thing I'd like to check out
here is whether the following interpretation of what my compiler
produces, in relation to function overloading on calls passing
rvalues and lvalues, is (even vaguely) correct and, then again,
expected.
<code>
#include <iostream>
void foo(int&) { std::cout << "foo(int&)\n"; }
void foo(int&&) { std::cout << "foo(int&&)\n"; }
template<typename T>
void bar(T&) { std::cout << "bar(T&)\n"; }
template<typename T>
void bar(T&&) { std::cout << "bar(T&&)\n"; }
int main()
{
int i = 0;
foo(0); // #1
foo(i); // #2
bar(0); // #3
//bar(i); // #4 Error: ambiguous
return 0;
}
</code>
To my current understanding, the two calls to foo show that, for
non-template functions it is possible to overload on rvalue and
lvalue references. The call foo(0) (#1, rvalue) selects foo(int&&)
while foo(i) (#2, lvalue) selects foo(int&).
However, for the overloaded template function bar, the situation
is significantly different since we have to take into account:
1. how template argument deduction is effected for template
functions declaring rvalue reference parameters; and
2. the rules for "reference collapsing."
If my understanding is correct, the call bar(0) (#3, rvalue) is
straightforward enough since the rvalue cannot bind to an lvalue
reference, and so
void bar<int>(int&&)
is instantiated, and used.
For the attempted call bar(i) (#4, lvalue), however, it seems
there will exist the two instantiations:
- void bar<int>(int& &); and
- void bar<int&>(int& &&)
where these become, after applying the reference collapsing rules:
- void bar<int>(int&); and
- void bar<int&>(int&)
and so disambiguation is not possible, hence the error (gcc-4.3.2).
Regards
Paul Bibbings
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]