The High Integrity C++ Standards suggest that rvalue arguments to functions can be deleted thus preventing implicit conversions.
http://www.codingstandard.com/rule/8-3-4
In your code, there is no difference in treatment between user-defined types and primitive types. The difference between the behaviour of these two lines:
foo(a);
foo(3.3);
is that a
is an lvalue, and 3.3
is an rvalue. The rvalue argument matches your overload 1
(which only accepts rvalues), the lvalue argument does not.
If you try to invoke foo
with an rvalue argument it will also match 1
and fail, e.g. foo(A{});
.