【问题标题】:What legitimate reasons exist to overload the unary operator&?有什么合理的理由使一元运算符&过载?
【发布时间】:2011-09-23 16:04:51
【问题描述】:

好的,我一直是inspired to do some head punching。似乎超载operator& 会导致不小的痛苦。

存在哪些合理的超载情况?

(不能说我曾经这样做过......)

【问题讨论】:

    标签: c++ operator-overloading


    【解决方案1】:

    我似乎记得类似智能指针类的东西,它覆盖了operator&,因为它想要返回包含指针的地址而不是智能指针对象的地址。不记得我在哪里看到的,也不记得当时它是否是个好主意。

    啊哈,记住了:微软的CComPtr

    编辑:概括地说,它可能在以下条件下有意义:

    • 您有一个伪装成其他对象的对象。
    • 此对象可以获得指向它所伪装的事物的指针。

    返回合法指针以外的任何东西都会违反principle of least astonishment

    【讨论】:

    • @Billy,我已经很长时间没有使用它了,我只是不记得优缺点了。由于传递接口指针的地址是 COM 编程中的常见操作,因此它似乎是有道理的。
    • "包含指针的地址" 你的意思是包含指针,不是吗?
    • @curiousguy 我不这么认为。包含的指针的类型为T *operator& 返回的指针类型为T **,并指向包含的指针。
    • CComPtr 中的 operator& 重载是一种危险的 hack。它仅在智能指针尚未初始化时才有效。否则,它已经拥有的对象不会减少其引用计数,并且泄漏比比皆是。在调试版本中,它实际上断言指针已经为空,因为这种错误太常见了。
    【解决方案2】:

    在用 lambda 占位符表示 & 操作时很有用,例如&_1[_2].

    【讨论】:

      【解决方案3】:

      重载一元 & 使您的 object 表现得像 reference(在这方面)。

      我很确定尝试提供内置引用的替代方案是愚蠢的,特别是因为引用在 C++ 中根本不是对象,而且它们没有自己的地址。您的用户定义类型的实例不可避免地是对象,并且确实具有地址,即使您禁用了获取该地址的正常方式。所以它从来都不是完美的模仿。

      但是,人们非常热衷于用户定义的指针替代方案,所以我可以看到有人可能想要尝试它。我不确定他们是否会避免创建一种(错误)行为方式会使其用户希望他们没有打扰的类型。

      【讨论】:

      • 但是isocpp.org/wiki/faq/references#overview-refs 说:“尽管在底层汇编语言中经常使用地址来实现引用,但请不要将引用视为指向对象的有趣指针。引用是对象。它不是指向对象的指针,也不是对象的副本。它是对象。"
      • @PravasiMeet:不幸的是他们这样说,因为标准明确表示引用不是对象。这就像变量的名称:变量是一个对象,但它的名称不是。引用的被引用对象是对象,但引用本身不是。
      • 你能告诉标准引文,明确指出引用不是对象吗?
      • @PravasiMeet:嗯,我认为有一个直截了当的声明,但目前我找不到它,所以它可能并不明确。然而,[intro.object] 说“一个对象是一个存储区域”,[dcl.ref] 在注释中说“引用可以被认为是一个对象的名称”,并且通常是“未指定是否或不是参考需要存储”。
      • 同样在FAQ中观察,首先它说“什么是引用?对象的别名(替代名称)”。因此,如果他们说引用是名称,引用是对象,那么只要他们说名称是对象,那么它们就是一致的。但是,就 C++ 标准的行话而言,对象的名称也不是对象。它在表达式中表示对象,这与对象相同,但在英语中“is”可以表示任何一种。
      【解决方案4】:

      我已经在生成 LLVM 代码的 DSL 上下文中做到了这一点,效果很好。将举例说明。假设xy 是值(即value 类型的对象)。然后表达式x+y 将 ADD 指令发送到某个代码流中。很明显,表达式&x 发出一条指令来获取x 的地址。

      【讨论】:

        【解决方案5】:

        四年后,另一个答案。

        我看到的另一个用途是当您捎带 C++ 语言,但定义自己的语义时。主要示例:Boost.Spirit。

        Boost.Spirit,尤其是用于解析的 Qi,重载解析器上的运算符,以提供类似 EBNF 的语法来指定任意解析器对象。特别是,一元 & 运算符被重载以提供 And-Predicate Parser

        与谓词解析器 (&a)

        说明

        句法谓词断言在评估另一个产生式之前要满足某个条件句法。与语义谓词 eps 类似,句法谓词不消耗任何输入。这 and-predicate, &a, 是一个肯定句法谓词,它返回一个 仅当谓词匹配时才匹配零长度。

        示例用法:

        基本前瞻示例:确保最后一个字符是 分号,但不要消耗它,只看下一个字符:

        test_phrase_parser("Hello ;", lit("Hello") >> &lit(';'), false);
        

        简而言之,这里的一元& 与指针完全没有关系;它具有适用于 Qi 解析器对象的领域特定语义。

        【讨论】:

        • 简而言之,与另一个表达式模板示例的答案相同
        【解决方案6】:

        曾经我将运算符 & (不改变其行为)重写为类私有,以防止偶尔创建指向堆栈中创建的对象的智能指针。仍然不确定这是否真的是个好主意...

        【讨论】:

        猜你喜欢
        • 2011-11-16
        • 1970-01-01
        • 2014-06-24
        • 2019-07-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-18
        • 2013-05-14
        相关资源
        最近更新 更多