我注意到,除了初始化之外,我还可以将初始化程序列表分配给STL容器,例如std::array和std::vector。例如:
#include <iostream>
#include <array>
#include <vector>
using namespace std;
int main()
{
array<int, 4> arr;
vector<int> vec(4);
arr = {{1, 2, 3, 4}};
vec = {4, 3, 2, 1};
cout << "arr: ";
for (auto elem : arr)
cout << elem << " ";
cout << "\nvec: ";
for (auto elem : vec)
cout << elem << " ";
cout << endl;
}
我只使用-std=C++11标志在Clang3.8.0上编译这段代码。我试图辨别这种行为是由C++11标准定义的,还是仅由编译器定义的。我一直在试图通过标准的相关部分(以及标准中的语言变得过于复杂时的cppreference.com ),到目前为止,我已经想出了以下内容:
初始化程序列出
5.17.9 -由用户定义的赋值运算符定义的赋值的右侧可能会出现大括号-init-列表。
std::数组
23.3.2.2:类数组依赖隐式声明的特殊成员函数.符合集装箱要求
std::向量
向量& operator=( std::initializer_list ilist );
从std::向量重载赋值操作符的语法来看,显然支持初始化程序列表的赋值。因此,我想知道是否将初始化程序列表传递给为STL容器隐式定义的重载赋值操作符(在我的示例中是std::array)是否是定义的行为?值得注意的是,std::数组是唯一带有隐式定义的重载赋值操作符的STL容器吗?
我看过相关问题的答案,例如:
然而,给出的答案并不符合我从编译器那里得到的行为,也不符合我从标准中解释的内容。此外,我正在寻找一个更普遍的问题的答案,而不仅仅是将列表初始化器分配给std::array。
发布于 2018-03-22 08:48:58
参见缺陷#1527,它将expr.ass/9中的措辞从“由用户定义的赋值操作符定义的赋值”改为“对类类型对象的赋值”,也就是说,运算符不必是用户定义的。我假设您使用的编译器已经实现了解决此缺陷的方法。
std::array
具有隐式定义的复制赋值operator=(const std::array&)
--这就是被调用的副本赋值,参数是通过聚合初始化构造的std::array
临时参数。
发布于 2018-03-22 08:50:08
没有为接受std::array
的initializer_list
定义赋值操作符。
但是,隐式定义赋值运算符(即std::array
本身)的参数可以从初始化程序列表中构造。这正是这里发生的事情。
请注意,这并不适用于内置数组,这些数组根本无法分配。
https://stackoverflow.com/questions/49433780
复制