Преобразования ClassType - оператор + неоднозначный - PullRequest
2 голосов
/ 20 марта 2011

В дальнейшем я ожидаю, что obj будет преобразовано в int, но почему он возвращает оператор + неоднозначный в следующем?

class MyClass
{
public:
    MyClass(int X = 0, double Y = 0):x(X), y(Y){}

    operator int() const  { return x; }
    operator double() const  { return y; }

private:
    int x;
    double y;
};

int main()
{
    MyClass obj(10, 20);

    int x = obj + 5; //obj converted to int
}

Ответы [ 3 ]

4 голосов
/ 20 марта 2011

Поскольку оба преобразования эквивалентны, это неоднозначно. Помните, что язык C ++ напрямую определяет + для аргументов double и int, стандартное преобразование не используется.

Так что ни одна из этих функций не лучше, чем другие:

  • double operator+ (double, int) - требуется одно преобразование, определенное пользователем, и без стандартных преобразований
  • int operator+ (int, int) - требуется одно преобразование, определенное пользователем, и без стандартных преобразований

Вам нужно будет самостоятельно предоставить все обычные арифметические операторы, если вы хотите, чтобы эта работа работала, и не полагаться на операторы неявного преобразования.

  • double operator+ (const MyClass&, int) - требуется одно стандартное преобразование
  • int operator+ (const MyClass&, double) - не требует преобразований

Теперь obj + 5 будет иметь однозначный лучший матч.


C ++ 0x черновик n3245 говорит, в разделе [over.built]

  • В этом подпункте термин повышенный целочисленный тип используется для обозначения тех целочисленных типов, которые сохраняются целочисленным продвижением (включая, например, int и long, но исключая, например, char). Точно так же термин повышенный арифметический тип относится к плавающим типам плюс повышенные целочисленные типы.

Для каждой пары повышенных арифметических типов L и R существуют операторные функции-кандидаты вида

LR operator*(L,  R);
LR operator/(L,  R);
LR operator+(L,  R);
LR operator-(L,  R);
bool       operator<(L,  R);
bool       operator>(L,  R);
bool       operator<=(L,  R);
bool       operator>=(L,  R);
bool       operator==(L,  R);
bool       operator!=(L,  R);

, где LR - результат обычных арифметических преобразований между типами L и R.

1 голос
/ 20 марта 2011

Конечно, вы можете решить эту проблему, перегрузив + operator в MyClass (в отличие от глобального в ответ Бена Фойгта ):

int operator +(const int rhs) const
{
    return x + rhs;
}

int operator +(const double rhs) const
{
    return y + rhs;
}

Опрятный и однозначный.

1 голос
/ 20 марта 2011

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

int x = static_cast<int>(obj) + 5; //obj converted to int
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...