Title
Conversions of operands of built-in operators
Status
c++14
Section
12.2.2.3 [over.match.oper]
Submitter
Richard Smith

Created on 2013-05-17.00:00:00 last changed 81 months ago

Messages

Date: 2014-02-15.00:00:00

[Moved to DR at the February, 2014 meeting.]

Date: 2014-01-15.00:00:00

Proposed resolution (January, 2014):

Change 12.2.2.3 [over.match.oper] paragraph 7 as follows:

If a built-in candidate is selected by overload resolution, the operands of class type are converted to the types of the corresponding parameters of the selected operation function, except that the second standard conversion sequence of a user-defined conversion sequence (12.2.4.2.3 [over.ics.user]) is not applied. Then the operator is treated as the corresponding built-in operator and interpreted according to Clause Clause 7 [expr]. [Example:

  struct X {
    operator double();
  };

  struct Y {
    operator int*();
  };

  int *a = Y() + 100.0; // error: pointer arithmetic requires integral operand
  int *b = Y() + X();   // error: pointer arithmetic requires integral operand

end example]

Date: 2020-12-15.00:00:00

Consider an example like:

  struct Y {
    operator int*();
  };

  extern int *p;
  int *a = p + 100.0;   // #1
  int *b = Y() + 100.0; // #2

#1 is ill-formed because it violates the requirement of 7.6.6 [expr.add] that the non-pointer operand have integral or enumeration type. It appears that #2 is well-formed, however, because 12.2.2.3 [over.match.oper] paragraph 7 says,

If a built-in candidate is selected by overload resolution, the operands are converted to the types of the corresponding parameters of the selected operation function. Then the operator is treated as the corresponding built-in operator and interpreted according to Clause Clause 7 [expr].

In this case, the selected operation function is

  int *operator+(int *, std::ptrdiff_t)

100.0 is thus converted to std::ptrdiff_t before reaching 7.6.6 [expr.add].

This problem could be addressed by restricting the conversion to the class or enumeration operand rather than both operands.

History
Date User Action Args
2014-11-24 00:00:00adminsetstatus: dr -> c++14
2014-03-03 00:00:00adminsetmessages: + msg4962
2014-03-03 00:00:00adminsetstatus: tentatively ready -> dr
2014-01-20 00:00:00adminsetmessages: + msg4737
2014-01-20 00:00:00adminsetstatus: drafting -> tentatively ready
2013-10-14 00:00:00adminsetstatus: open -> drafting
2013-05-17 00:00:00admincreate