Standard Template Library (STL) - std::map::operator=

Standard Template Library (STL) - 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. 保证,担保,抵押品,保证金

References

http://www.cplusplus.com/reference/map/map/operator=/

发布了443 篇原创文章 · 获赞 1685 · 访问量 101万+

猜你喜欢

转载自blog.csdn.net/chengyq116/article/details/104220542