【问题标题】:Error calling user-defined operator+ on temporary object when there are extra brackets当有额外的括号时,在临时对象上调用用户定义的 operator+ 时出错
【发布时间】:2013-05-14 13:42:30
【问题描述】:

如果我有一个用户定义的operator+(),如:

    class A
    {
    public:
        A operator+(A)
        {
            return A();
        }
    };

然后以下工作按预期工作:

    A a = A() + A();

但是 g++-4.7 给出了以下错误消息:

    A a = (A()) + A();

特别是错误消息是error: no match for ‘operator+’ in ‘+A()’
看起来(A()) 在表达式中被忽略了。

我的问题是:A a = (A()) + A(); 是否应该编译,如果没有,为什么不编译?

注意:当我执行 #define X (Identity()) 然后尝试执行 X + X 时,这发生在我身上。

【问题讨论】:

  • 有趣。如果您不知道,它会被视为一元加号运算符,例如 +5。
  • @chris 既然提到了,如果将示例更改为除法运算符,则不会发生错误,但对于加法、减法和乘法运算符会发生错误。在这种情况下,听起来它正在解析一元运算符而不是二元运算符。

标签: c++ operator-overloading most-vexing-parse


【解决方案1】:

这是一种强制转换语法。

原因是强制转换和一元加减乘法(取消引用运算符)比它们的二元对应物具有更高的优先级。由于此处的空格无关紧要,因此也可以理解为:

    A a = (A()) +A();

演员表和unary+ 的优先级高于二进制operator+,因此表达式采用前者的含义。

您可能想知道(和我一样)当里面的东西不是类型时如何进行转换。输入THE MOST VEXING PARSE!,这意味着我正在尝试将+A() 类型的对象强制转换为接受0 个参数并返回A 类型的对象的函数。

作为记录,语法:

    A a = ((A())) + A();

给出你想要的,因为双括号不能是强制转换,我们回到解析二进制 operator+ 表达式。

这也解释了为什么除法运算符而不是加法不会出现问题,它没有一元对应物。

【讨论】:

    猜你喜欢
    • 2013-05-08
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-20
    • 2017-09-28
    • 2010-12-04
    相关资源
    最近更新 更多