Последовательное приведение типов пользовательского типа в C ++ - PullRequest
3 голосов
/ 06 января 2012

Этот код компилируется и выполняется либо с открытым неявным приведением типа bool (закомментировано ниже, в http://ideone.com/FDJHB), либо с помощью открытого неявного преобразования типа int, за которым следует неявное приведение типа int к bool (как показано ниже, http://ideone.com/kHQ46). Тем не менее, сделав преобразование bool закрытым (закомментировано ниже, в http://ideone.com/4poze), возникает ошибка компиляции. Почему в этом случае маршрут через int больше не является опцией? Определенное поведение имеет последовательное приведение типа этого?Спасибо.

http://ideone.com/kHQ46

#include <iostream>

class MyObject {
 public:
  MyObject(int theInt) : theInt_(theInt) {
    return;
  }

  MyObject& operator=(MyObject& source) {
    std::cout << "assign op" << std::endl;
    theInt_ = source.theInt_;
    return *this;
  }

  friend MyObject operator*(MyObject& lhs, MyObject& rhs);

  operator int() {
    std::cout << "int conv" << std::endl;
    return theInt_;
  }

/*
  operator bool() {
    std::cout << "bool conv" << std::endl;
    return theInt_;
  }
*/

 private:

  int theInt_;

  MyObject(MyObject& source);
//  operator bool();

};

MyObject operator*(MyObject& lhs, MyObject& rhs) {
  std::cout << "mult op" << std::endl;
  return MyObject(lhs.theInt_*rhs.theInt_);
}


int main(int argc, char* argv[]) {

  MyObject a(1);
  MyObject b(2);
  MyObject c(3);

  if (a * b = c) std::cout << "Oh-no!" << std::endl;

  return 0;
}

РЕДАКТИРОВАТЬ: По запросу соответствующие сообщения компилятора.

1) Вывод для данного кода, приведенный к int в bool:

мультиоператор

int conv

назначить op

int conv

О-нет!

2) Вывод для кода с публичным приведением типа bool:

mult op

int conv

assign op

bool conv

Oh-нет!

3) Ошибка компилятора, если преобразование bool сделано приватным:

prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:34: error: ‘MyObject::operator bool()’ is private
prog.cpp:50: error: within this context

Ответы [ 2 ]

5 голосов
/ 06 января 2012

Чтобы преобразовать ваш тип в bool, компилятор выбирает «лучший» путь преобразования в соответствии с (довольно сложным) набором правил.

Если определено operator bool(), то это обеспечивает лучшее преобразование, чем operator int() с последующим преобразованием из int в bool; путь с меньшим количеством конверсий считается «лучшим».

Доступность не учитывается в этом процессе, поэтому он выберет operator bool(), даже если он является частным. Тогда компиляция не удастся, потому что operator bool() является приватным.

2 голосов
/ 06 января 2012

Короче говоря, компилятор выбирает, какой метод вызывать первым, а затем проверяет, разрешено ли его выполнять.Когда он видит operator bool, это лучшее совпадение для проверки if, поэтому он выбирает ее, а затем обнаруживает, что она закрыта и не может быть использована.

Также обратите внимание, что (a * b = c) назначаетc для временного значения, возвращаемого умножением, и затем оценивается, является ли оно нулевым или ненулевым.Я не могу придумать сценарий, где такая вещь была бы полезна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...