Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

2 overloads have similar conversions - built-in operator integer[pointer-to-object]

I have the following class:

class DictionaryRef {
public:
  operator bool() const;
  std::string const& operator[](std::string const& name) const;
  // ...
};

Then I try to use it:

DictionaryRef ref = ...;
ref["asdf"]; // error

The output complains about two overloads, but only lists one:

1>...: error C2666: 'DictionaryRef::operator []' : 2 overloads have similar conversions
1>    ...: could be 'const std::string &DictionaryRef::operator [](const std::string &) const'
1>    while trying to match the argument list '(DictionaryRef, const char *)'

However, mousing over the underlined portion, the popup window tells me that the second option is built-in operator integer[pointer-to-object]. Apparently it considers casting the object to bool, and then using the mysterious operator int[char const*]. I've never heard about this operator before, but apparently 3["asdf"] is the same as "asdf"[3]? Does anybody ever use this syntax or is it some really old remnant from C? Besides, wouldn't it need two conversions to get there - first from DictionaryRef to bool, and them from bool to int?

like image 616
riv Avatar asked Jul 07 '15 13:07

riv


1 Answers

It is counter intuitive but according to specification, subscripting is a commutative operator.

Paragraph 5.2.1 subscripting says :

A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type. The result is of type “T.” The type “T” shall be a completely-defined object type.64 The expression E1[E2] is identical (by definition) to *((E1)+(E2)).

That means that when xis an array, and i an integral, x[i] is *((x)+(i)) and is also i[x].

That's the reason for the operator int[char const *] : it is the same operation as the operator (char const *)[int].

For reference, C supports the same feature : in C language spec, 6.5.2.1 paragraph on array subscripting also says :

One of the expressions shall have type ‘‘pointer to complete object type’’, the other expression shall have integer type, and the result has type ‘‘type’’.

A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

like image 162
Serge Ballesta Avatar answered Sep 23 '22 23:09

Serge Ballesta