c++ - 为什么我可以在运算符 += 的右侧使用初始化列表而不是运算符 +?

标签 c++ operator-overloading initializer-list

这是 an earlier question about why I can't use a brace-enclosed initializer as an argument to operator+ 的后续事件,通过查看 this earlier question on the subject 已解决.

考虑以下 C++ 代码,您可以 try live at 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;
}

main 中使用 operator+ 和大括号括起来的初始值设定项列表的行无法编译(并且,在问了之前的问题之后,我现在知道为什么会这样了) .但是,我很困惑为什么在 main 中使用 operator+= 的代码确实编译得很好。

我很困惑为什么我可以重载 += 并让它正常工作,而重载 + 似乎在这里不起作用。标准中是否有特定规定允许在 += 运算符但不允许在 + 运算符的上下文中使用大括号括起来的初始化程序?或者这只是一个奇怪的编译器怪癖?

最佳答案

this question 的回答中有说明(与您链接的问题相关联)。

语言语法只允许在某些语法上下文中使用大括号列表,而不是代替任意表达式。该列表包括赋值运算符的右侧,但一般不包括运算符的右侧。

+=是一个赋值运算符,+不是。

赋值表达式的语法是:

  assignment-expression:
     conditional-expression
     logical-or-expression assignment-operator initializer-clause
     throw-expression
  assignment-operator: one of
      = *= *= /= %= += -= >>= <<= &= ^= |=
  

关于c++ - 为什么我可以在运算符 += 的右侧使用初始化列表而不是运算符 +?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42602382/

相关文章:

c++ - 为什么在 C++1z 的这个例子中,clang 和 g++ 为 a1.v 和 a2.v 打印 0?

c++ - 如何正确使用带有 C++ vector 的 kissFFT?

c# - .NET泛型中重载运算符约束的解决方案

c++ - 如何使用运算符编写可继承的模板类

c++ - 如何使用初始化列表构造 std::array 对象?

使用 SFINAE 的 C++ 好友模板

c++ - 编译器生成具有 constexpr 混淆行为的默认构造函数

c++ - 了解 C++ 中的运算符重载

c++ - g++ 和 clang 中的构造函数、初始化列表和不同行为

c++ - 从初始化列表就地构建 vector (对于带有构造函数参数的类)