Created on 2000-11-04.00:00:00 last changed 34 months ago
Additional note (August, 2010):
See issue 507 for a similar example involving comparison operators.
Additional note (August, 2010):
See issue 507 for a similar example involving comparison operators.
Notes from the 04/01 meeting:
The difference between initialization and assignment is disturbing. On the other hand, promotion is ubiquitous in the language, and this is the beginning of a very slippery slope (as the second report above demonstrates).
According to the Standard (although not implemented this way in most implementations), the following code exhibits non-intuitive behavior:
struct T { operator short() const; operator int() const; }; short s; void f(const T& t) { s = t; // surprisingly calls T::operator int() const }
The reason for this choice is 12.5 [over.built] paragraph 18:
For every triple (L, VQ, R), where L is an arithmetic type, VQ is either volatile or empty, and R is a promoted arithmetic type, there exist candidate operator functions of the form
VQ L& operator=(VQ L&, R);
Because R is a "promoted arithmetic type," the second argument to the built-in assignment operator is int, causing the unexpected choice of conversion function.
Suggested resolution: Provide built-in assignment operators for the unpromoted arithmetic types.
Related to the preceding, but not resolved by the suggested resolution, is the following problem. Given:
struct T { operator int() const; operator double() const; };
I believe the standard requires the following assignment to be ambiguous (even though I expect that would surprise the user):
double x; void f(const T& t) { x = t; }
The problem is that both of these built-in operator=()s exist (12.5 [over.built] paragraph 18):
double& operator=(double&, int); double& operator=(double&, double);
Both are an exact match on the first argument and a user conversion on the second. There is no rule that says one is a better match than the other.
The compilers that I have tried (even in their strictest setting) do not give a peep. I think they are not following the standard. They pick double& operator=(double&, double) and use T::operator double() const.
I hesitate to suggest changes to overload resolution, but a possible resolution might be to introduce a rule that, for built-in operator= only, also considers the conversion sequence from the second to the first type. This would also resolve the earlier question.
It would still leave x += t etc. ambiguous -- which might be the desired behavior and is the current behavior of some compilers.
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-02-18 07:47:23 | admin | set | messages: + msg6662 |
2013-10-14 00:00:00 | admin | set | status: drafting -> open |
2010-08-23 00:00:00 | admin | set | messages: + msg2863 |
2003-04-25 00:00:00 | admin | set | status: open -> drafting |
2001-05-20 00:00:00 | admin | set | messages: + msg511 |
2000-11-04 00:00:00 | admin | create |