开发者

unexpected behavior on casting

I have a doubt about how C++ casts types when it has to do math.

The code below as it is ( i.e. with only the cast to int without casting to double ) works and builds without problem. If I define ENABLE_DOUBLE_CAST doesn't build and complains about operator*. Do you know why?

The doubts I have are 2:

  1. why without the operator cast to double, it is used the one to int in a multiplication between double. Is it because of the implicit cast?
  2. why WITH the cast to double enable ( adding more clarity to the syntax ) that is not taken into consideration?

Thanks

AFG

class CA{
    int _m;
public:
    CA( int a, int b ){
     _m=a*b;
    }
    operator int (){
        std::cout<< "(CA int cast)" ;
        return _m;
    }
#ifdef ENABLE_DOUBLE_CAST
    operator double(){
        std::cout << "(CA double cat)";
        return 2.3 * _m;
    }
#endif
};

int main( int argc, const char** argv){开发者_Python百科
    CA obj_2( 10,20 );                  

    double total_1 = 100.0 * obj_2;   
    double total_2 = obj_2 * 100.0;
    return 0;
}


why without the operator cast to double, it is used the one to int in a multiplication between double. Is it because of the implicit cast?

Yes that is true.
It uses the operator int () to convert obj_2 to an int and then uses the inbuilt operator*(double, int)

why WITH the cast to double enabled ( adding more clarity to the syntax ) that is not taken into consideration?

When you provide both operator double() and operator int () for your class, it creates an ambiguity, whether to convert obj_2 to an int or double because there are two inbuilt operator overloads which it can use, namely:

operator*(double, int)
operator*(double, double)

Suggestion:
You should overload the operator* for your class if you want to avoid this problem of implicit conversions and ambiguity arising over it.

operator*(double,CA) and
operator*(CA,int) 


The reason is that with both casts you have ambiguous code, the compiler can't decide whether to use the int cast or the double cast, both are legal.

The rules on implicit casting are complicated and I'm not going to try and repeat them here (it would literally take pages and pages to cover everything). But if it generally agreed that to add implicit casts to your classes is a bad idea because of ambiguity issues like the one you have seen. If you want to use CA with operator* then it is better to define operator* for your class. E.g.

CA operator*(CA x, CA y)
{
  ...
}

CA operator*(CA x, int y)
{
  ...
}

CA operator*(CA x, double y)
{
  ...
}

CA operator*(int x, CA y)
{
  ...
}

CA operator*(double x, CA y)
{
  ...
}
0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜