C++ 否定算子与比较
让我们获取一些代码示例:C++ 否定算子与比较,c++,comparison,negation,C++,Comparison,Negation,让我们获取一些代码示例: ! 4 > 0; 从C++标准我们知道,否定首先要做,而不是比较。但是如果我们稍微扩展一下这个例子: #include <iostream> class Test { public: bool operator!() const { std::cout << "operator!" << std::endl; return false; } b
! 4 > 0;
从C++标准我们知道,否定首先要做,而不是比较。但是如果我们稍微扩展一下这个例子:
#include <iostream>
class Test
{
public:
bool operator!() const
{
std::cout << "operator!" << std::endl;
return false;
}
bool operator>(const int &) const
{
std::cout << "operator>" << std::endl;
return false;
}
};
int main(int argc, char * argv[])
{
Test t;
std::cout << "t > 0;" << std::endl;
t > 0;
std::cout << "! t > 0;" << std::endl;
! t > 0;
std::cout << "!t.operator>(0)" << std::endl;
! t.operator>(0);
return 0;
}
SomeObjInstance>0
调用不同于SomeObjInstance.operator>(0)
。我知道以第二种方式调用操作符(作为成员)并不常见,但为什么这种调用不同呢?我一直认为SomeObjInstance>0
会在后台转换为成员调用SomeObjInstance.operator>(0)
或函数调用bool operator>(const Test&,int)
,如果成员操作符不在场
这种行为在C++标准中描述,或者可能是某种未定义的行为?
< p>成员访问运算符<代码> *>代码>比否定操作符<代码>的优先级高。代码>这种行为在C++标准中描述,或者可能是某种未定义的行为?< /P> 这很可能是相关段落:
13.5超负荷操作员[超负荷操作] 5) 运算符函数通常不直接调用;而是调用它们来评估它们实现的操作符(13.5.1–13.5.7)。但是,可以使用运算符函数id作为函数调用语法(5.2.2)中的函数名显式调用它们 在您的第一个示例中t>0代码>它将使用具有关系比较运算符优先级的相应运算符。但是,在第二个版本中,t.operator>(0)
将其用作函数调用。因此,Test::operator>
被用作成员函数,这将导致您描述的行为,因为它失去了其运算符特征(“但是,可以在函数调用语法中使用运算符函数id作为函数名显式调用它们”)
另见:
和()
的优先级高于代码>。运算符语法解析为
(!t) > 0;
而显式调用被解析为
!((t.operator>)())
戴上你的编译帽一会儿。您需要根据一组明确的规则(包括运算符优先级)解析和计算表达式。求值涉及调用成员函数(operator>()
),如果表达式使用运算符
,该函数也会被调用,这又如何?您想做一个特例,并假设在这种情况下,默认优先级应该更改吗?你准备做多远?例如,如果间接调用此方法,或通过函数指针调用此方法?我认为这会使编译器的逻辑复杂化,并且仍然允许使用反直觉的示例,类似于您原来的问题。这很琐碎,OP显然知道。它不会回答所问的问题。谢谢您详细说明您的答案。@KamilKlimek:不客气。我仍然不确定是否有其他段落能更好地描述这种行为,但我找不到其他段落。
!((t.operator>)())