Standard Template Library (STL) -
std::map::operator=
std::map::operator=
public member function - 公开成员函数
1. std::map::operator=
C++98
copy (1) map& operator= (const map& x);
C++11
copy (1) map& operator= (const map& x);
move (2) map& operator= (map&& x);
initializer list (3) map& operator= (initializer_list<value_type> il);
Copy container content - 赋值给容器,替换容器内容
Assigns new contents to the container, replacing its current content.
将新内容分配给容器,替换其当前内容。
C++98
Copies all the elements from x
into the container, changing its size accordingly.
将所有元素从 x
复制到容器中,并相应地更改其大小。
The container preserves its current allocator, which is used to allocate additional storage if needed.
容器保留其当前的分配器,如果需要,该分配器用于分配其他存储。
C++11
The copy assignment (1) copies all the elements from x
into the container (with x
preserving its contents).
copy assignment (1) 将 x
中的所有元素复制到容器中 (x
保留其内容)。
复制赋值运算符。
The move assignment (2) moves the elements of x
into the container (x
is left in an unspecified but valid state).
move assignment (2) 将 x
的元素移动到容器中 (x
处于未指定但有效的状态)。
移动赋值运算符。
The initializer list assignment (3) copies the elements of il
into the container.
initializer list assignment (3) 将 il
的元素复制到容器中。
The new container size is the same as the size of x
(or il
) before the call.
新的容器大小与调用前的 x
(或 il
) 大小相同。
The container preserves its current allocator, except if the allocator traits indicate x
's allocator should propagate. This allocator is used (through its traits) to allocate or deallocate if there are changes in storage requirements, and to construct or destroy elements, if needed.
容器保留其当前的分配器,除非分配器特征指示 x
的分配器应传播。如果存储需求发生变化,则使用此分配器 (通过其特征) 分配或取消分配,并在需要时构造或销毁元素。
trait [treɪt]:n. 特性,特点,品质,少许
The elements stored in the container before the call are either assigned to or destroyed.
调用之前存储在容器中的元素将分配给或销毁。
2. Parameters
x
A map
object of the same type (i.e., with the same template parameters, key
, T
, Compare
and Alloc
).
相同类型的 map
对象 (即具有相同的模板参数,key
, T
, Compare
and Alloc
)。
il
An initializer_list
object. The compiler will automatically construct such objects from initializer list declarators.
一个 initializer_list
对象。编译器将根据初始化列表声明器自动构造此类对象。
Member type value_type
is the type of the elements in the container, defined in map as an alias of pair<const key_type, mapped_type>
(see map
member types).
成员类型 value_type
是容器中元素的类型,在 map
中定义为 pair<const key_type, mapped_type>
的别名 (请参见 map
成员类型)。
3. Return value
*this
4. Examples
4.1 std::map::operator=
//============================================================================
// Name : std::map::operator=
// Author : Yongqiang Cheng
// Version : Version 1.0.0
// Copyright : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <map>
int main()
{
std::map<char, int> first_map;
std::map<char, int> second_map;
first_map['x'] = 8;
first_map['y'] = 16;
first_map['z'] = 32;
second_map = first_map; // second_map now contains 3 ints
first_map = std::map<char, int>(); // and first_map is now empty
std::cout << "Size of first_map: " << first_map.size() << '\n';
std::cout << "Size of second_map: " << second_map.size() << '\n';
return 0;
}
Size of first_map: 0
Size of second_map: 3
4.2 std::map::operator=
//============================================================================
// Name : std::map::operator=
// Author : Yongqiang Cheng
// Version : Version 1.0.0
// Copyright : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <map>
#include <iostream>
void display_sizes(const std::map<int, int> &nums1,
const std::map<int, int> &nums2, const std::map<int, int> &nums3)
{
std::cout << "nums1: " << nums1.size() << " nums2: " << nums2.size()
<< " nums3: " << nums3.size() << '\n';
}
int main()
{
std::map<int, int> nums1
{
{ 3, 1 },
{ 4, 1 },
{ 5, 9 },
{ 6, 1 },
{ 7, 1 },
{ 8, 9 } };
std::map<int, int> nums2;
std::map<int, int> nums3;
std::cout << "Initially:\n";
display_sizes(nums1, nums2, nums3);
// copy assignment copies data from nums1 to nums2
nums2 = nums1;
std::cout << "After assigment:\n";
display_sizes(nums1, nums2, nums3);
// move assignment moves data from nums1 to nums3,
// modifying both nums1 and nums3
nums3 = std::move(nums1);
std::cout << "After move assigment:\n";
display_sizes(nums1, nums2, nums3);
return 0;
}
CDT Build Console
15:05:49 **** Incremental Build of configuration Debug for project hello_world ****
make all
Building file: ../src/hello_world.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/hello_world.d" -MT"src/hello_world.o" -o "src/hello_world.o" "../src/hello_world.cpp"
../src/hello_world.cpp: In function ‘int main()’:
../src/hello_world.cpp:22:2: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
{
^
../src/hello_world.cpp:28:12: error: in C++98 ‘nums1’ must be initialized by constructor, not by ‘{...}’
{ 8, 9 } };
^
../src/hello_world.cpp: In substitution of ‘template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator, const _Compare&, const allocator_type&) [with _InputIterator = <missing>]’:
../src/hello_world.cpp:28:12: required from here
../src/hello_world.cpp:28:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
../src/hello_world.cpp:28:12: error: no matching function for call to ‘std::map<int, int>::map(<brace-enclosed initializer list>)’
In file included from /usr/include/c++/5/map:61:0,
from ../src/hello_world.cpp:9:
/usr/include/c++/5/bits/stl_map.h:273:9: note: candidate: template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator, const _Compare&, const allocator_type&)
map(_InputIterator __first, _InputIterator __last,
^
/usr/include/c++/5/bits/stl_map.h:273:9: note: template argument deduction/substitution failed:
../src/hello_world.cpp:28:12: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11
{ 8, 9 } };
^
../src/hello_world.cpp:28:12: note: cannot convert ‘{5, 9}’ (type ‘<brace-enclosed initializer list>’) to type ‘const std::less<int>&’
In file included from /usr/include/c++/5/map:61:0,
from ../src/hello_world.cpp:9:
/usr/include/c++/5/bits/stl_map.h:256:9: note: candidate: template<class _InputIterator> std::map<_Key, _Tp, _Compare, _Alloc>::map(_InputIterator, _InputIterator)
map(_InputIterator __first, _InputIterator __last)
^
/usr/include/c++/5/bits/stl_map.h:256:9: note: template argument deduction/substitution failed:
../src/hello_world.cpp:28:12: note: candidate expects 2 arguments, 6 provided
{ 8, 9 } };
^
In file included from /usr/include/c++/5/map:61:0,
from ../src/hello_world.cpp:9:
/usr/include/c++/5/bits/stl_map.h:185:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(const std::map<_Key, _Tp, _Compare, _Alloc>&) [with _Key = int; _Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >]
map(const map& __x)
^
/usr/include/c++/5/bits/stl_map.h:185:7: note: candidate expects 1 argument, 6 provided
/usr/include/c++/5/bits/stl_map.h:174:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map(const _Compare&, const allocator_type&) [with _Key = int; _Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::allocator_type = std::allocator<std::pair<const int, int> >]
map(const _Compare& __comp,
^
/usr/include/c++/5/bits/stl_map.h:174:7: note: candidate expects 2 arguments, 6 provided
/usr/include/c++/5/bits/stl_map.h:162:7: note: candidate: std::map<_Key, _Tp, _Compare, _Alloc>::map() [with _Key = int; _Tp = int; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, int> >]
map()
^
/usr/include/c++/5/bits/stl_map.h:162:7: note: candidate expects 0 arguments, 6 provided
../src/hello_world.cpp:43:10: error: ‘move’ is not a member of ‘std’
nums3 = std::move(nums1);
^
make: *** [src/hello_world.o] Error 1
src/subdir.mk:18: recipe for target 'src/hello_world.o' failed
15:05:50 Build Finished (took 570ms)
Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> GCC C++ Compiler -> Dialect
Language standard: ISO C++11 (-std=c++0x)
CDT Build Console
15:21:53 **** Build of configuration Debug for project hello_world ****
make all
Building file: ../src/hello_world.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/hello_world.d" -MT"src/hello_world.o" -o "src/hello_world.o" "../src/hello_world.cpp"
Finished building: ../src/hello_world.cpp
Building target: hello_world
Invoking: GCC C++ Linker
g++ -o "hello_world" ./src/hello_world.o
Finished building target: hello_world
15:21:54 Build Finished (took 899ms)
Initially:
nums1: 6 nums2: 0 nums3: 0
After assigment:
nums1: 6 nums2: 6 nums3: 0
After move assigment:
nums1: 0 nums2: 6 nums3: 6
4.3 std::map::operator=
//============================================================================
// Name : std::map::operator=
// Author : Yongqiang Cheng
// Version : Version 1.0.0
// Copyright : Copyright (c) 2019 Yongqiang Cheng
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<int, string> map_data;
map_data[1] = "cheng";
map_data[3] = "yong";
map_data[2] = "qiang";
cout << "before" << endl;
map<int, string>::iterator iter;
for (iter = map_data.begin(); iter != map_data.end(); iter++)
{
cout << iter->first << " : " << iter->second << endl;
}
string temp_string = map_data[6];
cout << "after" << endl;
for (iter = map_data.begin(); iter != map_data.end(); iter++)
{
cout << iter->first << " : " << iter->second << endl;
}
return 0;
}
before
1 : cheng
2 : qiang
3 : yong
after
1 : cheng
2 : qiang
3 : yong
6 :
5. Complexity - 复杂度
For the copy assignment (1): Linear in sizes (destructions, copies).
For the move assignment (2): Linear in current container size (destructions).*
For the initializer list assignment (3): Up to logarithmic in sizes (destructions, move-assignments) – linear if il
is already sorted.
* Additional complexity for assignments if allocators do not propagate.
propagate [ˈprɒpəɡeɪt]:vt. 传播,传送,繁殖,宣传 vi. 繁殖,增殖
destruction [dɪˈstrʌkʃn]:n. 破坏,毁灭,摧毁
6. Iterator validity - 迭代器有效性
All iterators, references and pointers related to this container are invalidated.
与该容器相关的所有迭代器、引用和指针均无效。
In the move assignment, iterators, pointers and references referring to elements in x
are also invalidated.
在移动分配中,引用 x
中元素的迭代器、指针和引用也将无效。
7. Data races - 数据竞争
All copied elements are accessed.
The move assignment (2) modifies x
.
The container and all its elements are modified.
8. Exception safety - 异常安全性
Basic guarantee: if an exception is thrown, the container is in a valid state.
基本保证:如果引发异常,则容器处于有效状态。
If allocator_traits::construct
is not supported with the appropriate arguments for the element constructions, or if value_type
is not copy assignable (or move assignable for (2)), it causes undefined behavior.
如果元素构造的适当参数不支持 allocator_traits::construct
,或者 value_type
不可复制赋值 (或 (2) 的可移动赋值),它将导致未定义的行为。
guarantee [.ɡærən'tiː]:v. 保证,保障,担保,确保 n. 保证,担保,抵押品,保证金