开发者

c++ overload operator resolution

I'm learning c++ and using C++ Primer. Consider the following exercise 14.46:

 class Complex {
     Complex(double);
     // ...
 };

 class LongDouble {

     friend LongDouble operator+(LongDouble&, int);  // (1)

 public:
     LongDouble(int);

     operator double();

     LongDouble operator+(const Complex &);  // (2)
     // ...
  };

 LongDouble operator+(开发者_运维知识库const LongDouble &, double);  // (3)

 LongDouble ld(16.08);
 double res = ld + 15.05; // which operator+ ?

When I compile using gcc 4.5 the above program, I get

14_46.cpp:60:21: error: ambiguous overload for ‘operator+’ in ‘ld + 1.5050000000000000710542735760100185871124267578125e+1’
14_46.cpp:60:21: note: candidates are: operator+(double, double) <built-in>
14_46.cpp:35:5: note:                 LongDouble LongDouble::operator+(const Complex&)
14_46.cpp:45:1: note:                 LongDouble operator+(const LongDouble&, double)
14_46.cpp:17:5: note:                 LongDouble operator+(LongDouble&, int)

Why is (3) not selected ? Isn't it exact match?

However, I noticed that removing const-ness of parameter in (3) matches exactly, i.e.,

LongDouble operator+(LongDouble &, double);  // (4)

Using (4) there is no ambiguity. Am I missing something here?


You have the following competing user defined functions (candidates)

operator+(LongDouble&, int); // friend
operator+(LongDouble&, Complex const&); // member
operator+(LongDouble const&, double); // global

You are invoking this with arguments:

(LongDouble&, double)

For the first argument, the first two candidates are better than the last. For the second argument, the last candidate is better than the first two candidates. No candidate has at least as good matches as all the others for all arguments, and better matches for some arguments.

You cannot figure out a clear winner for this situation. This is what I like to call the "criss cross".

There are builtin candidates too that are considered among user defined candidates.

operator+(double, double);
operator+(int, double);
...

From all the builtin candidates, operator+(double, double) would match best. But that would require a user defined conversion for the first argument, which is worse than all the three other user defined operators for the first argument, so it cannot win either.


My preferred way to fix this would be to add const to version 1:

friend LongDouble operator+(const LongDouble&, int);  // (1)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜