Ошибка возникает из-за того, что компилятор обнаруживает, что может делать что-то по-разному, поскольку приведение неявно, компилятору необходимо выбрать «правильный путь».
Начиная с вашего случая: компилятор не может сделать что-то вроде
(int) c;
Он не знает как, но он может привести c к чему-то, что он знает, как привести к int, но это оставляет два варианта:
(int) A(c);
(int) B(c);
Оба одинаково действительны и очень разные! Нет способа узнать, что реализовать. На самом деле, вы можете даже столкнуться с проблемой, если у вас есть переменная b типа B, так как вы можете привести два пути:
(int) b;
(int) A(b);
Если бы компилятор выбрал один путь, вы бы не знали, какой, а разные компиляторы могут выбирать разные варианты!
Итак, каковы некоторые решения:
Сделайте приведение типов от B к A, C к B и C к A явным. Затем создайте
функция приведения, которая сначала преобразует это в нужный вам класс, и
затем приводит это к int. Это, хотя не будет работать с визуальным
студия, которую вы используете, так что это не будет работать для вашего случая.
Сделайте класс B защищенным, но, так как вы хотите, чтобы C был приведен как B, это не работает.
Из-за проблемы при приведении B к int вы не можете просто сделать A защищенным.
Определите операцию приведения в A, но сделайте так, чтобы она вызывала виртуальную функцию, которая B
переопределение. Таким образом, есть только одна операция приведения, определенная в A,
без двусмысленного случая.
Я думаю, что третий вариант - лучший в вашем случае, он будет выглядеть примерно так:
#include <stdio.h>
class A
{
protected:
virtual int _int_cast() const
{
return 1;
}
public:
operator int() const
{
return this->_int_cast();
}
};
class B : public virtual A
{
protected:
virtual int _int_cast() const
{
return 2;
}
};
class C : public virtual A, public virtual B
{
public:
};
int main()
{
C c;
int i = (int)c;
printf("%d\n", i);
return 0;
}
В основном: не переопределяйте перегруженные приведения из классов, которые вы наследуете, предположите, что он должен сначала преобразоваться в базовый класс. Также следите за перегруженными приведениями, которые очень похожи, например, вы можете преобразовать в int, а затем в const int или просто привести непосредственно к const int.