Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If the first operand of an additive expression is convertible to both pointer and integer, which conversion is chosen?

In the following example, which conversion function should be called? Why should that one be chosen over the other?

struct A
{
  operator int();
  operator int*();
};

A x;
int i = x + 1;

The compiler chooses operator int().. but why?

Here are some relevant quotes from C++03:

From [expr.add]

For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a pointer to a completely defined object type and the other shall have integral or enumeration type.

From [conv]

expressions with a given type will be implicitly converted to other types in several contexts:

  • When used as operands of operators. The operator’s requirements for its operands dictate the destination type
like image 469
willj Avatar asked Jul 15 '13 22:07

willj


1 Answers

The reason for this behavior is that the built-in operator which accepts a pointer as its left hand operand accepts an object of type std::ptrdiff_t as its right hand operand. This is specified in § 13.6 of the C++11 Standard:

For every cv-qualified or cv-unqualified object type T there exist candidate operator functions of the form

T * operator+(T *, std::ptrdiff_t);

[...]

Since 1 has type int, the compiler considers the built-in operator + that takes two ints as a better choice, because it onlys require a (user-defined) conversion for the first argument.

If you provided an argument of type std::ptrdiff_t as the right hand operand of operator +, you would see the expected ambiguity:

int i = x + static_cast<std::ptrdiff_t>(1); // AMBIGUOUS!

Here is a live example.

like image 68
Andy Prowl Avatar answered Oct 22 '22 17:10

Andy Prowl