这里是C ++标准的摘录(实际上是c ++ 14草案,但我认为这段经文在当前的C ++ 11标准中是相同的):
运算符函数应该是非静态成员函数或者是非成员函数 至少一个参数,其类型是类,对类的引用,枚举或对引用的引用 列举。无法更改运算符的优先级,分组或操作数。 可以更改为每种类型预定义的运算符=,(一元)&和(逗号)的含义 通过定义实现这些运算符的运算符函数来定义特定类和枚举类型。操作者 函数的继承方式与其他基类函数相同。
因此,据我所知,将1类类型和一类非类型作为参数运算符>>(,)是完全合法的。该标准没有说“第一个”或“第二个”参数。其中只有“一个”必须是班级类型。
这是一个令我惊讶的代码片段:
int operator>> ( int v, std::function<int(int)> transformer )
{
int v1 = transformer(v);
DGS::CLogger::GetLogger()->Log<int>(&IntFormatter, v1 );
return v1;
}
static int DoItLoggedAndCompact( int value )
{
int x = operator>>( operator>>(value, DoIt) , AnotherIntCalculation ); // compiles and works!
return x;
// The following line produces (with clang++):
// error: invalid operands to binary expression ('int' and 'int (*)(int)')
// return value >> DoIt >> AnotherIntCalculation; :
}
请注意“函数指针不是类类型”,而作为正确的语句,并不是一个全面的答案。正如您在以int x = ...
开头的重写代码和运算符&gt;&gt;的定义中看到的那样第二个参数,函数指针静默转换为std :: function。
我无法在标准中的任何地方找到一条说明这两个(据称)同义形式的转换规则不同的段落。
那么,这是一个编译器错误,社区范围内对C ++规范的过度解释还是......我们在这里看到的其他东西?或者只是我的一些愚蠢的疏忽?
答案 0 :(得分:6)
但“函数指针不是类类型” 是正确答案。
第13.6条中有以下注释:
仅当操作数表达式最初具有类时,才会发生运算符重载决策 或枚举类型
规范性规则见13.3.1.2(强调我的):
如果表达式中的运算符的操作数没有类型或枚举类型,则假定运算符是内置运算符,并根据第5章进行解释。
如果任一操作数的类型是类或枚举,则可能会声明用户定义的运算符函数来实现此运算符,或者转换操作数可能需要用户定义的转换到适合内置运算符的类型。在这种情况下,重载决策用于确定调用哪个运算符函数或内置运算符来实现运算符。因此,运算符表示法首先转换为等效的函数调用符号,如表11所示。
仅当其中一个操作数是类类型时,表单才是同义词。由于这两个都不在,所以不会重写为operator>>()
。