Per my understanding of C++ standard section ยง12.3.2, the following piece of code should not compile: $ cat c.cxx #include <iostream> struct V { (&operator double ())[3] { return v; } double v[3]; }; static void Print( const double (&a)[3] ) { std::cout << a[0] << "," << a[1] << "," << a[2] << std::endl; } int main() { V v = {0,1,2}; Print( v ); return 0; } Seems to be valid c++ for gcc 5.2.1: $ g++ -Wall -W -pedantic c.cxx && ./a.out 0,1,2 The only accepted syntax should be using a `typedef` keyword: typedef double (&array_ref)[3]; operator array_ref () { return v; }
Here is the output from clang++: error: cannot specify any part of a return type in the declaration of a conversion function; use a typedef to declare a conversion to 'double (&)[3]' % clang++ --version Debian clang version 11.0.1-2
Reduced: struct V { (&operator double ())[3] { return v; } double v[3]; }; static void Print( const double (&)[3] ) { } int main() { V v = {0,1,2}; Print( v ); } EDG accepts it too. MSVC says: error C2586: incorrect user-defined conversion syntax: illegal indirections
This is also erroneously named with `operator double`: assert(V{0,1,2}.operator double()[1] == 1.0); using T = double; assert(V{0,1,2}.operator T()[1] == 1.0); using U = double(&)[3]; // 'struct V' has no member named 'operator U' // V{0,1,2}.operator U(); And a similar thing happens with user defined conversions to function pointers / references