Function Overloading Based on Value vs. Const Reference

Solution 1:

The intent seems to be to differenciate between invocations with temporaries (i.e. 9) and 'regular' argument passing. The first case may allow the function implementation to employ optimizations since it is clear that the arguments will be disposed afterwards (which is absolutely senseless for integer literals, but may make sense for user-defined objects).

However, the current C++ language standard does not offer a way to overload specifically for the 'l/r-valueness' of arguments - any l-value being passed as argument to a function can be implicitly converted to a reference, so the ambiguity is unavoidable.

C++11 introduces a new tool for a similar purpose — using r-value references, you can overload as follows

void foo(int x)        { ... }
void foo(const int &&x) { ... }

... and foo(4) (a temporary, r-value passed as argument) would cause the compiler to pick the second overload while int i = 2; foo(i) would pick the first.

(note: even with the new toolchain, it is not possible to differentiate between the cases 2 and 3 in your sample!)

Solution 2:

You could do this with a template:

template<typename T> void foo(T x) { ... }

Then you can call this template by value or by reference:

int x = 123;
foo<int>(x);  // by value
foo<int const&>(x);  // by refernce

Solution 3:

How would the caller be able to differentiate between them?

It cannot be differentiated in this case. Both the overloaded functions have the same type of primitive data type as the argument. And taking by reference doesn't count for a different type.