Comment by HarHarVeryFunny
Comment by HarHarVeryFunny 9 hours ago
Ah, yes, unfortunately the language says that a value parameter of type T and an rvalue parameter of type T (T&&) are both equal priority "exact matches" to a call passing an rvalue argument, but at least if that was the only difference between two functions you'd get an ambiguous overload compilation error rather than it just selecting an unexpected one.
A workaround for this, if you want an rvalue parameter to match an rvalue argument during overload resolution, is to make the alternate "value" (vs rvalue) overload a const reference argument vs a value one.
So, if you have f(T&&) and f(T), and call f(std::move(t)) then you'll get an ambiguous overload compilation error, but if you instead had f(T&&) and f(const T&), then f(std::move(t)) will match the rvalue one as you may hope for.
>So, if you have f(T&&) and f(T), and call f(std::move(t)) then you'll get an ambiguous overload compilation error [...]
Okay, but that's not what I'm saying. I'm not talking about the program being invalid, I'm talking about the program being confusing to the programmer, which is what this article is about. Sure, in that case the program is ill-formed. What if you have f(const T &, double) and f(T, int)? If you call f(x, 0) you cause a copy, and if you call f(x, 0.0) you don't. A programmer who's not aware that the second overload exists will not realize this is happening, in the same way that he will not realize std::move() is not moving anything if they don't realize, for example, that the argument is const.