Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
392 views
in Technique[技术] by (71.8m points)

c++ - «F(5)» and «int x; F(x)» to call different functions?

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
"; }
void F(int& v) { cout << "variable
"; }

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).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.

void f(int const&); // #1
void f(int&);       // #2

In this matter, the following decisions are done

int x = 0;
int const y = x;
int const z = 1;

f(1); // #1
f(x); // #2
f(y); // #1
f(z); // #1

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

template<int N> void f(); // #1
void f(int n);            // #2

It behaves like this then:

int x = 0;
int const y = x;
int const z = 1;

f<1>(); // #1
f(1);   // #2
f<y>(); // error, y not an ICE
f<z>(); // #1
f(x);   // #2

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...