在C++ 11中查找运算符的规则

Mar*_*ski 15 c++ c++11

N3337,"工作草案,编程语言C++标准",在第13.3.1.2节中给出了以下示例,p.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+
}
Run Code Online (Sandbox Code Playgroud)

但是,这只是一个注意事项:

注意:表达式中运算符的查找规则与函数调用中运算符函数名称的查找规则不同,如以下示例所示:

我的问题是标准中的哪个位置表明这是必须发生的事情,而不仅仅是用一个例子来说明?

据我所知,根据第13.3.1.2条,p.2,运算符表达式转换为运算符函数调用.那么为什么以及如何在上面的例子中有所不同呢?

编辑:

在调查问题之后,我认为我可能忽略了这一点.同一条款中的第3和第6页一起声明全局候选人和成员候选人在查找运算符时被认为是平等的(因此查找规则与说明不同).但是,我对这个问题的调查是由这个例子引起的,它以与GCC 4.8和Clang相同的方式编译:

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
}
Run Code Online (Sandbox Code Playgroud)

当直接调用运算符函数时,为什么块作用域声明会出现阴影,而运算符表达式调用时却没有?

以下是海湾合作委员会的错误:

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
                 ^
Run Code Online (Sandbox Code Playgroud)

在这里来自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);
                     ^
Run Code Online (Sandbox Code Playgroud)

编译器是否正确使块声明在一种情况下影响全局名称而不是另一种情况?

Jes*_*ood 1

编译器是否正确地让块声明在一种情况下遮蔽全局名称,而在另一种情况下则不然?

我得出的结论是两个编译器都是错误的。我相信x + y;也应该失败。13.3.1.2p3 明确指出:

非成员候选集是根据非限定函数调用 (3.4.2) 中名称查找的常用规则在表达式上下文中对运算符@进行非限定查找的结果,但忽略所有成员函数。

因此,您的示例中x + y;和之间应该没有区别。Commeau online 的代码出现以下错误:operator+(x, y);

"ComeauTest.c", line 11: error: no operator "+" matches these operands
            operand types are: X + Y
    x + y;  // OK
      ^
"ComeauTest.c", line 13: error: no suitable user-defined conversion from "Y"
 to "X"
          exists
    operator+(x, y);  // error
Run Code Online (Sandbox Code Playgroud)