0

所以昨天我问了这个问题私人朋友运营商<< 关于如何operator<<为班级设为私人。我得到了一个很好的答案,它完全按照我的意愿工作,但我还有一些其他问题。

首先,我不明白代理类为什么不必成为朋友private_printable?我怎么可能private_printable从内部访问内部成员operator<<

其次,在使用答案中的代码时,我写了这个:

operator proxy () const { return *this; }

起初它对我来说似乎没问题,它甚至可以编译,但是当我运行它并得到一个段错误时,我意识到我没有为代理类定义任何构造函数,它将private_printable作为参数并因此允许转换。那么我的代码怎么可能编译,甚至没有给我任何警告?

然后我做的第三件事是给代理一个构造函数,它有一个引用private_printable作为它的参数(我没有让它显式),而不是定义转换运算符。现在一切都很好,只是又可以打电话operator<<private_printable。但我不太确定,为什么会这样。是因为 ADL 吗?我对它有一些模糊的理解,但我不确定它的所有细节。无论如何,这proxy门课是私人的,那么为什么 ADL 会有所作为呢?

4

1 回答 1

1
  1. 可以访问的operator<<成员,private_printable因为它是friendprivate_printable。它不是一个friendproxy

  2. return *this返回一个private_printable对象,该对象必须隐式转换为proxy. 如何转换private_printableproxy?打电话private_printable::operator proxy ()。但这就是我们已经使用的功能!段错误是由无限递归的堆栈溢出引起的。对于它的价值,无限循环将是另一种可能的结果。

  3. explicit构造函数也是一个转换函数,与operator proxy. ADL 有点涉及,就像operator proxy使用了但没有构造函数一样。解决办法当然是制作constructor explicit。只有当构造函数的唯一操作数是代理类时,才会出现问题。

proxy仅当您明确命名时,作为成员的类private才重要。ADL 仍然可以找到带有proxy参数的函数,然后间接导致对转换函数的访问,因为类类型的使用不受访问限定的影响。只有名称查找受到影响。private同样,如果您只有一个成员类型,您总是可以使用typedef它。

于 2013-03-27T13:02:32.100 回答