I’d like to write two distinct functions to handle a constant value and a variable of a given type (viz., int).
Here is the example test case:
int main(void) {
int x=12;
F(5); // this should print "constant"
F(x); // this should print "variable"
}
I thought it would be enough to define:
void F(int v) { cout << "constant\n"; }
void F(int& v) { cout << "variable\n"; }
This assumes that the compiler will choose int& for variables as “better specialized” and int for constants as the only choice). However, G++ this is the result:
test.cc: In function ‘int main()’:
test.cc:13: error: call of overloaded ‘F(int&)’ is ambiguous // for line: F(x);
test.cc:4: note: candidates are: void F(int)
test.cc:5: note: void F(int&)
G++ does choose F(int) for constants but does not know which function to choose for variables.
Does anyone have any idea why this happens?
Background: I am experimenting with prolog-like unification methods in C++. Being able to know the difference between constants and variables would help me choosing desired unification behavior (assignment or comparison) in cases such as functor(x,5) <=> functor(3,5).
If what you want is to differentiate between a compile time constant and a non-compile time constant – then you have no chance. That’s not possible.
But if you want to differentiate between a non-constant variable and between a constant variable (and everything else included – like literals), then you can overload a function with a const-reference and non-const reference parameter. For this scenario, the C++ Standard introduces extra rules that make this otherwise ambiguous case not ambiguous.
In this matter, the following decisions are done
Note how it can’t differentiate between y and z, even though value of z is a compile time constant (termed integral constant expression, or ICE), while y is not.
What you can do is to only accept compile time values then. Overload the function so that one is a template and the other isn’t
It behaves like this then: