0

I'm reading C++ Templates - The Complete Guide, 2nd Edition, and B.2.1 tells about implicit conversion of the implied "this" argument.

Same example here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1592.pdf

Depending on the typedef of ptrdiff_t, the compiler may deduce that there is an ambiguity between BadString::operator[] and converting the implied "this" argument to char * and using the built-in subscript operator.

Can somebody please explain how is obj[0] expression related to this conversion and why compiler acts the way it acts in three examples below?

Thank you.

int main() {
    abc x;
    auto first = x[1];
    auto second = x + 2;
    return 0;
}

Works (why?):

struct abc
{
    operator bool *() { return {}; }
};

Doesn't work (why):

struct abc
{
    template <typename T>
    operator T *() = delete;
};

template <>
abc::operator int *() { return {}; }

Doesn't work (use of overloaded operator '[]' is ambiguous):

struct abc
{
    operator bool *() { return {}; }
    template <typename T>
    operator T *() = delete;
};

template <>
abc::operator int *() { return {}; }
curiousguy
  • 8,038
  • 2
  • 40
  • 58
NoRegsz
  • 21
  • 2
  • "_Explicit constructors (**including copy constructors**) were added to prevent unintended conversions being silently called by the compiler_" doesn't make much sense. The first C++ std specified that an implementation should suppress the programmer if he tried to create such beast – curiousguy Jan 25 '19 at 05:02
  • `= delete` doesn't remove things from the overload set. Notice that the specialization of the template isn't changing anything, same ambiguity error from https://rextester.com/OXE95586 – Ben Voigt Jan 25 '19 at 05:04
  • "_a conversion would also make the compiler uncomplainingly accept code which was semantic nonsense:_" Assuming types A and B can both be converted to a boolean, testing if they convert to the same boolean is well defined and not "semantic nonsense". The paper OTOH spouts nonsense. `operator char* (); operator char const* ();` providing both conversions is really bizarre – curiousguy Jan 25 '19 at 05:07
  • `= delete` is irrelevant, the intent is not to remove this template operation from the overload set, just to make sure `int` specialization is the only one available for use. – NoRegsz Jan 25 '19 at 05:11

0 Answers0