неожиданное поведение на кастинге - PullRequest
0 голосов
/ 21 августа 2011

У меня есть сомнения по поводу того, как в C ++ приводятся типы при выполнении математических операций.

Приведенный ниже код (т.е. только с приведением к int без приведения к удвоению) работает и собирается без проблем.Если я определяю ENABLE_DOUBLE_CAST, не строит и жалуется на operator*.Ты знаешь почему?

У меня есть два сомнения:

  1. , почему без оператора, приведенного к удвоению, используется умножение на int при умножении на double.Это из-за неявного приведения?
  2. , почему WITH приведение к двойному включению (добавление большей ясности в синтаксис) не принимается во внимание?1016 * 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){
        CA obj_2( 10,20 );                  
    
        double total_1 = 100.0 * obj_2;   
        double total_2 = obj_2 * 100.0;
        return 0;
    }
    

Ответы [ 2 ]

3 голосов
/ 21 августа 2011

почему без оператора, приведенного к типу double, используется тот, который используется для умножения на double. Это из-за неявного приведения?

Да, это правда.
Он использует operator int () для преобразования obj_2 в int, а затем использует встроенный operator*(double, int)

почему с включенным приведением к double (добавление большей ясности к синтаксису), который не учитывается?

Когда вы предоставляете как operator double(), так и operator int () для своего класса, это создает двусмысленность, будь то преобразование obj_2 в int или double, потому что есть две встроенные перегрузки операторов, которые он может использовать, а именно:

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

Предложение:
Вам следует перегружать operator* для вашего класса, если вы хотите избежать этой проблемы неявных преобразований и возникновения двусмысленности над ней.

operator*(double,CA) and
operator*(CA,int) 
1 голос
/ 21 августа 2011

Причина в том, что с обоими приведениями у вас неоднозначный код, компилятор не может решить, использовать ли приведение типа int или двойное приведение, оба допустимы.

Правила неявного приведения сложны, и я не собираюсь повторять их здесь (буквально потребуются страницы и страницы, чтобы охватить все). Но если все согласны с тем, что добавление неявных приведений к вашим классам - плохая идея из-за проблем с неоднозначностью, подобных той, которую вы видели. Если вы хотите использовать CA с оператором *, то лучше определить оператор * для вашего класса. Э.Г.

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