Просто чтобы быть ясно:
B b = 5;
является "копией инициализации" не уступка. (См. http://www.gotw.ca/gotw/036.htm).
В этом случае, вы просите компилятор для выполнения двух неявных определенных пользователем преобразований первого, т.е. int -> A, A -> B
перед временным B
объект передается в конструктор копирования для B b
. Компилятору разрешено удалять временный объект, но семантически вы все еще просите язык сделать два перехода по типам.
Все неявное поведение в языках программирования по своей сути страшно. Ради небольшого синтаксического сахара мы просим C++ «сделать какую-то магию, чтобы она просто работала». Неожиданные преобразования типов могут разрушить хаос в крупных сложных программах. В противном случае каждый раз, когда вы написали новую функцию или новый класс, вам придется беспокоиться обо всех других типах и функциях, которые могут повлиять на нее, при этом побочные эффекты размываются по вашему коду. Вы действительно хотите неявных преобразований от int
->apple
->horse
->horse_power
->aeroplane
?
По этой причине, C++ допускает только одну неявного определенного пользователя преобразования:
12.3 [класс преобразований.conv]
1 Тип преобразования объектов класса может быть задан конструкторами и функциями преобразования. Эти преобразования называются пользовательскими преобразованиями и используются для неявных преобразований типов (раздел 4), для инициализации (8.5) и для явных преобразований типов (5.4, 5.2.9).
4 Не более чем одно определяемое пользователем преобразование (конструктор или функция преобразования) неявно применяется к одному значению.
Вы лучше либо с помощью явного приведения или «прямой инициализации» оба из которых делают его ясно компилятор и соавторы именно то, что вы пытаетесь сделать. Либо традиционный, либо новый синтаксис синтаксиса:
B b(5);
B b{5};
B b = {5};
Нет, вы не можете сделать это неявно. – jrok
Почему я не могу сделать это неявно? –
Пробовал добавлять оператор присваивания из A, например 'B & operator = (const A & a);' или 'B & operator = (A a);'? – Daemin