问题
Consider this snippet of C++ code:
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;
}
Why doesn't this compile? Is there a specific reason this wasn't included in the C++ standard? Or an equivalent does indeed exist and I'm just using it wrong?
回答1:
For pretty much all other operators, your conversion operator would do exactly what you want, and it would continue to do exactly what you want even if you add custom operators.
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;
}
However, =
is special, the rules for =
are different compared to most other operators. As identified by T.C.:
13.3.1.2 Operators in expressions [over.match.oper]
4 For the built-in assignment operators, conversions of the left operand are restricted as follows:
(4.1) -- no temporaries are introduced to hold the left operand, and
(4.2) -- no user-defined conversions are applied to the left operand to achieve a type match with the left-most parameter of a built-in candidate.
Together with the fact that any custom operator=
is not allowed to be defined as a global function, this makes sure that foo=bar;
where foo
is a class type always means foo.operator=(bar);
, nothing else.
The fact that this one operator is singled out doesn't explain the reason, but does make it quite clear that it's an intentional decision, and making sure that foo=bar;
always means foo.operator=(bar);
, nothing else, by itself already seems like a valid reason.
回答2:
Implicit conversion is only done in the following cases:
Implicit conversions are performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2; in particular:
- when the expression is used as the argument when calling a function that is declared with T2 as parameter;
- when the expression is used as an operand with an operator that expects T2;
- when initializing a new object of type T2, including return statement in a function returning T2;
- when the expression is used in a switch statement (T2 is integral type);
- when the expression is used in an if statement or a loop (T2 is bool).
None of those is the case here. Instead the compiler is trying to find a suitable operator=
to work with a double
. To have this compile you need to overload that operator ( you actually want a float
as seen in the code ):
Foo& operator=(float other)
{
value = f;
return *this;
}
And change your assignment to foo = 1.0f;
Your conversion function would work with for example:
float f = foo;
来源:https://stackoverflow.com/questions/39936865/c-assign-to-implicitly-converted-lvalue