在Google C ++样式指南中,有Operator Overloading部分有一个奇怪的陈述:
重载也令人惊讶 后果。例如,你不能 forward声明重载的类
operator&
。
这似乎不正确,我无法找到任何导致GCC出现问题的代码。有谁知道那句话是指什么?
答案 0 :(得分:20)
5.3.1标准具有“可以采用不完整类型的对象的地址,但如果该对象的完整类型是声明operator&()作为成员函数的类类型,那么行为是未定义(并且不需要诊断)。“
我也不知道这一点,但正如另一张海报所指出的那样,很容易看出它如何导致编译器生成错误的代码。
答案 1 :(得分:16)
我也没有听说过,但这会在重载之前和之后为相同的代码提供可能令人困惑的结果:
#include <iostream>
class Foo;
void bar (Foo& foo) {
std::cout << &foo << std::endl;
}
class Foo {
public:
bool operator & () { return true; }
};
void baz (Foo& foo) {
std::cout << &foo << std::endl;
}
int main () {
Foo foo;
bar(foo);
baz(foo);
return 0;
}
输出:
0x7fff092c55df
1
尽管还有其他原因导致你不这样做 - 重载地址 - 不能很好地与stl或更通用的代码一起使用。
答案 2 :(得分:6)
我认为这句话并不准确。和其他答案一样,我猜这里。首先,我假设他们指的是unary operator& and not binary operator&。那就是:
int x = 5;
int* p = &x; // unary &
if (x & 1) // binary &
您可以转发声明您想要的任何课程。但是,如果该类超载一元运算符&amp;,并且您调用一元运算符&amp;在指向其中一个对象的指针上,您可能会得到不一致的行为(有时您只是获取地址,有时您会调用重载方法)。这很容易变成几乎无法调试的东西。
我很高兴fizzer实际上看了标准并且不仅仅是猜测。
答案 3 :(得分:1)
由于能够超载操作员和boost库提供handy template addressof()来处理查找类的真实地址。并不是说我建议你重载operator&amp;,但如果你需要,可以提供帮助。
答案 4 :(得分:0)
编辑注释:
这是猜测,但转发声明的主要原因之一是能够声明指向该类的指针。在得到定义之前,编译器必须对类进行假设 - 例如,指针的大小。
是否可以通过重载运算符来改变T *的大小。换一个T? (编辑:评论员 - 我认为不是) - 但
重载运算符&amp ;;违反了什么假设 - 它如何改变课程?
这是一种方式。
我可以写:
class A;
void f(A& x) {
A* xPointer = &x;
}
如果operator&amp;()重载,那么它有一个新的意义,编译器可能认为它可以为它生成代码,但这是错误的。
答案 5 :(得分:0)
措辞不清楚,你当然可以向前宣布这个类 - 但是规则显然是采取你不应该在类重载operator&
的位置。
其他编码标准中也存在类似的规则,例如JSF(pdf)规则159规定operator&
不应过载。