Regeln für die Suche nach Operatoren in C ++ 11

N3337"Working Draft, Standard für Programmiersprache C ++" enthält das folgende Beispiel in Abschnitt 13.3.1.2, S. 34. 10:

struct A { };
void operator + (A, A);
struct B {
  void operator + (B);
  void f ();
};
A a;
void B::f() {
  operator+ (a,a);   // error: global operator hidden by member
  a + a;             // OK: calls global operator+
}

Dies ist jedoch nur eine Anmerkung:

Anmerkung: Die Suchregeln für Operatoren in Ausdrücken unterscheiden sich von den Suchregeln für Operatorfunktionsnamen in einem Funktionsaufruf, wie im folgenden Beispiel gezeigt:

Meine Frage ist, wo in der Norm steht, dass dies geschehen muss, anstatt nur die Notiz mit einem Beispiel zu haben?

Soweit ich das beurteilen kann, laut Ziffer 13.3.1.2, S. In 2 werden Operatorausdrücke in Operatorfunktionsaufrufe konvertiert. Warum und wie sollte es im obigen Beispiel einen Unterschied geben?

Bearbeiten:

Nachdem ich mir das Problem angeschaut habe, glaube ich, dass ich p übersehen habe. 3 und S.6 in derselben Klausel, in der gemeinsam angegeben wird, dass globale Kandidaten und Mitgliedskandidaten bei der Suche nach Operatoren gleichermaßen berücksichtigt werden (daher unterscheiden sich die Suchregeln, wie in der Anmerkung angegeben). Meine Untersuchung zu diesem Thema ergab sich jedoch aus diesem Beispiel, das auf die gleiche Weise mit GCC 4.8 und Clang kompiliert wird:

struct X {};  struct Y {};

void operator+(X, X) { }
void operator+(X, Y) { }

void test() {
  void operator+(X, X);
  X x; Y y;

  x + x;  // OK
  x + y;  // OK

  operator+(x, y);  // error
  operator+(x, x);  // OK
}

Warum wird die Deklaration des Blockumfangs abgeschattet, wenn die Operatorfunktion direkt aufgerufen wird, aber nicht, wenn sie vom Operatorausdruck aufgerufen wird?

Hier sind die Fehler von GCC:

operators-main-ss.cpp: In function ‘void test()’:
operators-main-ss.cpp:13:17: error: could not convert ‘y’ from ‘Y’ to ‘X’
   operator+(x, y);  // error
                 ^

Und hier von Clang:

operators-main-ss.cpp:13:16: error: no viable conversion from 'Y' to 'X'
  operator+(x, y);  // error
               ^
operators-main-ss.cpp:1:8: note: candidate constructor (the implicit copy constructor) not viable: no
      known conversion from 'Y' to 'const X &' for 1st argument;
struct X {};  struct Y {};
       ^
operators-main-ss.cpp:7:22: note: passing argument to parameter here
  void operator+(X, X);
                     ^

Sind die Compiler korrekt, damit die Blockdeklaration in einem Fall den globalen Namen, nicht aber den anderen Namen abdeckt?

Antworten auf die Frage(3)

Ihre Antwort auf die Frage