Рассмотрим этот фрагмент кода C ++:
struct Foo {
float value;
operator float& () {
return this->value;
}
};
int main() {
Foo foo;
foo=1.0f; //Doesn't compile, foo isn't implicitly converted to a float&
return 0;
}
Почему это не компилируется? Есть ли конкретная причина, по которой это не было включено в стандарт C ++? Или эквивалент действительно существует, и я просто использую его неправильно?
Практически для всех других операторов ваш оператор преобразования будет делать именно то, что вы хотите, и он будет продолжать делать именно то, что вы хотите, даже если вы добавите пользовательские операторы.
struct Foo {
float value;
operator float& () { return this->value; }
Foo &operator+=(Foo);
};
int main() {
Foo foo {};
foo+=1.0; // compiles and works
// equivalent to foo.operator float&()+=1.0;
}
Тем не мение, =
особенный, правила для =
отличаются по сравнению с большинством других операторов. Как установлено Т.С .:
13.3.1.2 Операторы в выражениях [over.match.oper]
4 Для встроенных операторов присваивания преобразования левого операнда ограничены следующим образом:
(4.1) — не вводятся временные символы для удержания левого операнда, и
(4.2) — пользовательские преобразования не применяются к левому операнду для достижения соответствия типа с крайним левым параметром встроенного кандидата.
Вместе с тем, что любой обычай operator=
не может быть определена как глобальная функция, это гарантирует, что foo=bar;
где foo
это тип класса всегда означает foo.operator=(bar);
, ничего больше.
Тот факт, что этот один оператор выделен, не объясняет причину, но дает понять, что это преднамеренное решение, и убедиться, что foo=bar;
всегда значит foo.operator=(bar);
Ничто иное, само по себе уже не кажется веской причиной.
Неявное преобразование выполняется только в следующих случаях:
Неявные преобразования выполняются всякий раз, когда выражение какого-либо типа
T1 используется в контексте, который не принимает этот тип, но принимает некоторые
другой тип T2; особенно:
- когда выражение используется в качестве аргумента при вызове функции, объявленной с параметром T2;
- когда выражение используется в качестве операнда с оператором, который ожидает T2;
- при инициализации нового объекта типа T2, включая инструкцию return в функции, возвращающей T2;
- когда выражение используется в операторе switch (T2 является целочисленным типом);
- когда выражение используется в операторе if или цикле (T2 — bool).
Ни один из них не имеет место здесь. Вместо этого компилятор пытается найти подходящий operator=
работать с double
, Чтобы получить эту компиляцию, вам нужно перегрузить этот оператор (вы на самом деле хотите float
как видно из кода):
Foo& operator=(float other)
{
value = f;
return *this;
}
И измените свое назначение на foo = 1.0f;
Ваша функция преобразования будет работать, например:
float f = foo;