简体   繁体   English

为什么我可以在operator + =的右侧使用初始化列表,但不能使用operator +?

[英]Why can I use initializer lists on the right-hand side of operator += but not operator+?

This is a follow-up to an earlier question about why I can't use a brace-enclosed initializer as an argument to operator+ , which was resolved by looking at this earlier question on the subject . 这是一个早期问题的后续问题,为什么我不能使用大括号括起初始化器作为operator+的参数 ,这是通过查看前面关于该主题的问题来解决的

Consider the following C++ code, which you can try live at ideone.com : 考虑以下C ++代码,您可以在ideone.com上试用

#include <iostream>
#include <initializer_list>
using namespace std;

struct AddInitializerList {
    void operator+= (initializer_list<int> values) {
        // Do nothing   
    }

    void operator+ (initializer_list<int> values) {
        // Do nothing
    }
};

int main() {
    AddInitializerList adder;
    adder += {1, 2, 3};  // Totally legit
    adder +  {1, 2, 3};  // Not okay!

    return 0;
}

The line in main that uses operator+ with a brace-enclosed initializer list does not compile (and, after asking that earlier question, I now know why this is). main中使用operator+和大括号括起初始化列表的行不能编译(并且在询问之前的问题后,我现在知道为什么会这样)。 However, I'm confused why the code that uses opeartor+= in main does indeed compile just fine. 但是,我很困惑为什么在main中使用opeartor+=的代码确实编译得很好。

I'm confused as to precisely why I can overload += and have it work just fine, while overloading + doesn't seem to work here. 我很困惑,为什么我可以重载+=并让它工作得很好,而重载+似乎在这里工作。 Is there a particular provision in the standard that permits brace-enclosed initializers in the context of the += operator but not the + operator? 标准中是否有特定的规定允许在+=运算符但不包含+运算符的上下文中使用括号括起的初始值设定项? Or is this just a weird compiler quirk? 或者这只是一个奇怪的编译器怪癖?

It is explained in the answer to this question (which is linked from the question you linked to). 这个问题的答案(与您链接的问题相关联) 对此进行了解释。

The language grammar only allows a braced list in certain grammatical contexts, not in place of an arbitrary expression. 语言语法只允许某些语法上下文中的支撑列表,而不是任意表达式。 That list includes the right-hand side of assignment operators, but NOT the right-hand side of operators in general. 该列表包括赋值运算符的右侧,但不包括运算符的右侧。

+= is an assignment operator, + is not. +=是赋值运算符, +不是。

The grammar for assignment expressions is: 赋值表达式的语法是:

\n  assignment-expression: 赋值表达式:\n     conditional-expression 条件表达式\n     logical-or-expression assignment-operator initializer-clause logical-or-expression assignment-operator initializer-clause\n     throw-expression 扔表达\n  assignment-operator: one of 赋值运算符:一个\n      \n  = *= *= /= %= += -= >>= <<= &= ^= |= 

C++14 §5.17/9: C ++14§5.17/ 9:

A braced-init-list may appear on the right-hand side of braced-init-list可能出现在右侧

  • an assignment to a scalar, in which case the initializer list shall have at most a single element. 标量的赋值,在这种情况下,初始化列表最多只能包含一个元素。 The meaning of x={v} , where T is the scalar type of the expression x , is that of x=T{v} . x={v}的含义,其中T是表达式x的标量类型,是x=T{v}的含义。 The meaning of x={} is x=T{} . x={}的含义是x=T{}
  • an assignment to an object of class type, in which case the initializer list is passed as the argument to the assignment operator function selected by overload resolution (13.5.3, 13.3). 对类类型对象的赋值,在这种情况下,初始化列表作为参数传递给由重载决策(13.5.3,13.3)选择的赋值运算符函数。

This applies to a += b via its $5.7/7 equivalence to a = a + b (except that a is evaluated only once for += ). 这适用于一个 +=通过其$ 5.7 / 7等价BA = 一个 + B(不同之处在于一个用于只计算一次+= )。 Put another way, due to a comment by MM, because of the equivalence for the built-in operators += is regarded as an assignment operator, and not a special update operator. 换句话说,由于MM的评论,由于内置运算符的等价性, +=被视为赋值运算符,而不是特殊的更新运算符。 Hence the quoted text above about “assignment” applies to += . 因此,上面关于“赋值”的引用文本适用于+=

+= operator is a compound assignment . +=运算符是复合赋值 The standard explicitly permits initializer lists on the right-hand side of assignments: 该标准明确允许在赋值右侧的初始化列表:

§8.5.4/1 [...] Note: List-initialization can be used §8.5.4/ 1 [...]注意:可以使用列表初始化

... ...

— on the right-hand side of an assignment (5.17) - 在作业的右侧(5.17)

§5.17 talks about all assignments, including compound ones: §5.17谈论所有任务,包括复合任务:

assignment-expression: 赋值表达式:
- conditional-expression - 条件表达式
- logical-or-expression assignment-operator initializer-clause - logical-or-expression assignment-operator initializer-clause
- throw-expression - throw-expression

assignment-operator: one of 赋值运算符:一个
= *= /= %= += -= >>= <<= &= ˆ= |= = *= /= %= += -= >>= <<= &= ˆ= |=

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当对象位于赋值的右侧时,重载赋值运算符 - Overloading assignment operator when the object is on the right-hand side of the assignment 二进制“ [”:找不到使用“初始化列表”类型的右侧操作数的运算符(或者没有可接受的转换) - binary '[': no operator found which takes a right-hand operand of type 'initializer list' (or there is no acceptable conversion) 为什么我不能将 operator+ 与 reverse_iterator 一起使用? - Why I can't use operator+ with reverse_iterator? 我如何克服此错误C2679:二进制&#39;&gt;&gt;&#39;:未找到采用&#39;const char []&#39;类型的右侧操作数的运算符 - how I can overcome this error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char []' 错误:未找到需要右侧QUdpSocket的运算符 - error: no operator found which takes a right-hand QUdpSocket C ++没有找到需要右手操作数的&lt;&lt;运算符 - C++ No << operator found which takes right-hand operand 重载插入运算符:未找到采用“ unsigned int”类型的右侧操作数的运算符(或者没有可接受的转换) - Overloading Insertion Operator: no operator found which takes a right-hand operand of type 'unsigned int' (or there is no acceptable conversion) 二进制&#39;operator&#39;:未找到采用&#39;Fraction&#39;类型的右侧操作数的运算符(或没有可接受的转换) - Binary 'operator' : no operator found which takes a right-hand operand of type 'Fraction' (or there is no acceptable conversion) 为链表重载 operator+ - Overloading operator+ for linked lists 左右运算符+重载 - operator+ overload left and right
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM