一元&运算符有哪些特殊规则适用?

20

一元 & 运算符是否有特殊规则?

例如,下面这段代码:

#include <iostream>
struct X
{
    X() {}
    void* operator &() { return NULL; }
};
int main()
{
    const X x;
    std::cout << &x << std::endl;
    X y;
    std::cout << &y;
}

产生输出结果

0xbfbccb33
0

我知道这段代码会像这样编译和运行,因为之前在这里讨论过,但如果我不知道的话,我本来会预期编译失败,因为 operator & 没有声明为 const

看起来编译器会生成 operator &() const,无论是否重载了 operator &()。很好,这很有道理,特别是与示例和输出一致。

问题是,在标准中详细说明了这种行为吗?

我不想要重复我在问题中已经陈述的答案,请不要解释我的重载运算符不能在一个 const 对象上调用,因为我已经知道。


4
这是C++语言。我相信标准中存在某些不太为人所知的隐藏细节、特殊规则、边缘情况或其他内容,但是斯特劳斯特先生觉得它很有用... - user529758
抱歉Luchian,我没有看到后缀。它必须在扣除和声明中都包含。我也会去寻找。至少我能做的就是考虑到你向我指出了这个区别 =P - WhozCraig
有点令人担忧,我有一些定义了operator&的代码,但没有定义明显有问题的const版本,而我从未意识到这一点。 - jcoder
不是运算符的重载,而是const和非const的限定导致了不同的行为,因为潜在的候选重载选择可能不会被采用,因为它没有限定。我认为实际上可能是13.3.1(5)和13.6两者都有关。 - WhozCraig
1
@J99:这里存在一个冲突。类的作者通常不知道类的使用者是“真正想要对象的地址”,还是“想要对象的逻辑地址”。因此,要么有很多破损的代码在使用 & 时应该使用 std::addressof / boost::addressof,要么就根本不应该重载 operator&。从形式上讲,前者是正确的(依赖于 & 获取地址的代码应该记录必须这样做),实际上,后者是正确的(将具有重载 operator& 的类型传递到该代码中的人违反了隐式接口)。 - Steve Jessop
显示剩余5条评论
1个回答

14

n3337 13.3.1.2/9

如果该运算符是运算符“,”、“一元运算符&”或运算符->,且没有可行函数,则假定运算符是内置运算符,并根据第5条解释。


我完全同意这个答案。问题在于可行性,我认为这取决于操作符的隐式对象参数,并且稍后在13.3.1.(4-5)中有所涵盖。先生,你的回答完全正确。+1! - WhozCraig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接