C++ std::forward_list 基本用法

#include <iostream>
#include <string>
#include <forward_list>

using namespace std;

// https://zh.cppreference.com/w/cpp/container/forward_list

std::ostream& operator<<(std::ostream& ostr, const std::forward_list<int>& list)
{
	for (auto &i : list) {
		ostr << " " << i;
	}
	return ostr;
}

class item
{
public:
	item() = delete;

	item(const int& a, const int& b)
		: m_a(a), m_b(b)
	{}

	bool operator< (const item& comp) const
	{
		return m_a*m_b < comp.m_a*comp.m_b;
	}

	bool operator== (const item& comp) const
	{
		return m_a==comp.m_a && m_b==comp.m_b;
	}

private:
	int m_a;
	int m_b;
};

bool compAB(int a, int b)
{
	return a + 1 < b;
}

int main()
{
	int a[] = { 1,2,3 };
	forward_list<int> lis;
	forward_list<int>  lis2(4);
	forward_list<int>  lis3(4, 5);
	forward_list<item> lis5(4, item(1, 2));
	forward_list<item> lis6(4, { 1, 2 });
	forward_list<item> lis7(lis6);
	forward_list<int>  lis8(a, a + 3);
	forward_list<item> lis9(lis7.begin(), lis7.end());
	forward_list<int>  lis4({ 1,2,3 });

	//////////////////////////////////////////////////////////////////////////

	int v_front = lis4.front();

	std::forward_list<int>::iterator
		it_bb = lis4.before_begin(); // 返回指向第一个元素之前迭代器
	auto cit_bb = lis4.cbefore_begin();

	auto it_b = lis4.begin();
	auto cit_b = lis4.cbegin();

	auto it_e = lis4.end();
	auto cit_e = lis4.cend();

	//////////////////////////////////////////////////////////////////////////

	// 没有 size 

	bool isEmpty = lis4.empty();
	size_t max_size = lis4.max_size(); // 并非实际可以申请到的大小

	//////////////////////////////////////////////////////////////////////////

	lis4.clear();
	lis4 = { 1,2,3 };

	// iterator insert_after(const_iterator pos, const T& value);
	lis4.insert_after(lis4.before_begin(), 77); // 78 1 2 3
	lis4.insert_after(lis4.begin(), 78); // 77 78 1 2 3

	// iterator insert_after( const_iterator pos, size_type count, const T& value );
	lis4.insert_after(lis4.before_begin(), 2, 79); // 79 79 78 1 2 3

	forward_list<int>  lis10({ 10,20,30 });
	// template< class InputIt >
	// iterator insert_after(const_iterator pos, InputIt first, InputIt last);
	lis4.insert_after(lis4.before_begin(), lis10.begin(), lis10.end()); // 10 20 30 79 79 78 1 2 3

	lis4.insert_after(lis4.before_begin(), { 11,22 }); // 11 22 10 20 30 79 79 78 1 2 3

	//////////////////////////////////////////////////////////////////////////

	// 在容器中的指定位置后插入新元素。原位构造元素,即不进行复制或移动操作。
	lis4.emplace_after(lis4.begin(), 555); // 11 555 22 10 20 30 79 79 78 1 2 3

	// iterator erase_after( const_iterator pos );
	// 从容器移除指定元素。
	lis4.erase_after(lis4.begin()); // 11 22 10 20 30 79 79 78 1 2 3

	//////////////////////////////////////////////////////////////////////////

	lis4.push_front(666); // 666 11 22 10 20 30 79 79 78 1 2 3
	lis4.emplace_front(777); // 777 666 11 22 10 20 30 79 79 78 1 2 3
	lis4.pop_front(); // 666 11 22 10 20 30 79 79 78 1 2 3

	//////////////////////////////////////////////////////////////////////////

	lis4.resize(2); // 缩小,保留前两个
	lis4.resize(5); // 放大,补默认值,这里是 0

	lis4.swap(lis8);

	//////////////////////////////////////////////////////////////////////////

	// merge: 排序后,把 2 的元素 移动 到 1 中。
	{
		std::forward_list<int> list1 = { 5,9,0,1,3,10,0 };
		std::forward_list<int> list2 = { 8,7,2,6,4 };

		list1.sort();
		list2.sort();
		std::cout << "list1:  " << list1 << "\n";
		std::cout << "list2:  " << list2 << "\n";
		list1.merge(list2); // 必须是有序的,元素的 < 必须有定义。// lis2 变为空
		std::cout << "merged: " << list1 << "\n";
	}

	{
		std::forward_list<int> list1 = { 5,9,0,1,3 };
		std::forward_list<int> list2 = { 8,7,2,6,4 };

		list1.sort();
		list2.sort();
		std::cout << "list1:  " << list1 << "\n";
		std::cout << "list2:  " << list2 << "\n";
		list1.merge(list2, [](int a, int b) { return a + 1 < b; }); // 自定义 < 的比较方法,lambda 表达式。// lis2 变为空
		std::cout << "merged: " << list1 << "\n";
	}

	{
		std::forward_list<int> list1 = { 5,9,0,1,3 };
		std::forward_list<int> list2 = { 8,7,2,6,4 };

		list1.sort();
		list2.sort();
		std::cout << "list1:  " << list1 << "\n";
		std::cout << "list2:  " << list2 << "\n";
		list1.merge(list2, compAB); // 函数名。// lis2 变为空
		std::cout << "merged: " << list1 << "\n";
	}

	//////////////////////////////////////////////////////////////////////////

	{
		forward_list<int>  lis11({ 10,20,30 });
		forward_list<int>  lis12({ 101,201,301 });

		// void splice_after( const_iterator pos, forward_list& other );
		lis11.splice_after(lis11.before_begin(), lis12); // 101,201,301 10,20,30
	}

	{
		forward_list<int>  lis11({ 10,20,30 });
		forward_list<int>  lis12({ 101,201,301 });
		// void splice_after( const_iterator pos, forward_list& other, const_iterator it );
		lis11.splice_after(lis11.before_begin(), lis12, lis12.begin()); // 201 10,20,30 // 迭代器的后一个元素
	}

	{
		forward_list<int>  lis11({ 10,20,30 });
		forward_list<int>  lis12({ 101,201,301 });
		auto it12 = lis12.begin();
		std::advance(it12, 2);
		// void splice_after( const_iterator pos, forward_list& other,
		// const_iterator first, const_iterator last );
		lis11.splice_after(lis11.before_begin(), lis12, lis12.before_begin(), it12); // 101,201 10,20,30 // 最后的两个迭代器,是开集
	}

	//////////////////////////////////////////////////////////////////////////

	{
		std::forward_list<int> l = { 1,100,2,3,10,1,11,-1,12 };

		l.remove(1); // 移除两个等于 1 的元素
		l.remove_if([](int n) { return n > 10; }); // 移除全部大于 10 的元素

		for (int n : l) {
			std::cout << n << ‘ ‘;
		}
		std::cout << ‘\n‘;
	}

	//////////////////////////////////////////////////////////////////////////

	// 逆转容器中的元素顺序。不非法化任何引用或迭代器。
	forward_list<int>  lis13({ 10,20,30 });
	lis13.reverse();

	//////////////////////////////////////////////////////////////////////////
	// 从容器移除所有 相邻 的重复元素。只留下相等元素组中的第一个元素。
	{
		std::forward_list<int> x = { 1, 2, 2, 3, 3, 2, 1, 1, 2 };

		std::cout << "contents before:";
		for (auto val : x)
			std::cout << ‘ ‘ << val;
		std::cout << ‘\n‘;

		x.unique(); // 1 2 3 2 1 2
		std::cout << "contents after unique():";
		for (auto val : x)
			std::cout << ‘ ‘ << val;
		std::cout << ‘\n‘;

		return 0;
	}

	//////////////////////////////////////////////////////////////////////////
	// sort
	{
		std::forward_list<int> list = { 8,7,5,9,0,1,3,2,6,4 };

		std::cout << "before:     " << list << "\n";
		list.sort(); // 默认升序
		std::cout << "ascending:  " << list << "\n";
		list.sort(std::greater<int>()); // 降序
		std::cout << "descending: " << list << "\n";

		// 类,要重载 <
		// 或者,传参 lambda 表达式
	}

}

  

原文地址:https://www.cnblogs.com/alexYuin/p/12045972.html

时间: 2024-10-15 03:24:42

C++ std::forward_list 基本用法的相关文章

QLinkedList和std::forward_list(都是双向链表,不支持operator[],好处可能是插入和删除都比较快)

forward_list forward_list是C++11版本才有的.forward_list被实现为单链表,而list是一个双向链表,所以forward_list要比list高效一些.forward_list设计的时候就是追求效率的,跟我们自己写的C格式的单链表一样的高效. 考虑到效率问题,forward_list没有size成员函数.由于它本质是一个链表,有一个size成员会耗费常量的时间来计数其大小.这将需要一些额外的空间而且会降低插入和删除操作的效率.如果要获得forward_lis

C++ std::map::erase用法及其陷阱

1.引入: STL的map中有一个erase方法用来从一个map中删除制定的节点 eg: map<string,string> mapTest; typedef map<string,string>::iterator ITER; ITER iter=mapTest.find(key); mapTest.erase(iter); 像上面这种删除单个节点,map的行为不会出现问题,但是当在一个循环里用的时候,往往会被误用. 2.陷阱 eg: for(ITER iter=mapTest

C++ std::pair的用法

1 pair的应用 pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存.另一个应用是,当一个函数需要返回2个数据的时候,可以选择pair. pair的实现是一个结构体,主要的两个成员变量是first second 因为是使用struct不是class,所以可以直接使用pair的成员变量. 2 make_pair函数 template pair make_pair(T1 a, T2 b) { return pair(a

STL std::pair基本用法

std::pair 是一个结构体模板,其可于一个单元内存储两个相异对象.是 std::tuple 的拥有两个元素的特殊情况. 一般来说,pair 可以封装任意类型的对象,可以生成各种不同的 std::pair<T1, T2> 对象,可以是数组对象或者包含 std::pair<T1,T2> 的 vector 容器.pair 还可以封装两个序列容器或两个序列容器的指针. 1. 定义 #include <utility> template<class T1, class

C++ std::vector 基本用法2

#include <iostream> #include <vector> using namespace std; int main() { int ar[10] = { 1,2,3,4,5,6,7,8,9,0 }; std::vector<int> vec5(ar, ar + 10); // reverse size_t cap1 = vec5.capacity(); // = 10 vec5.reserve(20); // = Request a change i

C++ std::array 基本用法

#include <iostream> #include <string> #include <array> using namespace std; // https://zh.cppreference.com/w/cpp/container/array int main() { ///array<int, 3> arr({ 1,2,3 }); // 非法 array<int, 3> arr1{ { 1,2,3 } }; // 不可以扩容,属于

C++ std::list 基本用法

#include <iostream> #include <string> #include <list> using namespace std; // https://zh.cppreference.com/w/cpp/container/list /* * std::list 是支持常数时间从容器任何位置插入和移除元素的容器.不支持快速随机访问.它通常实现为双向链表. * * 在 list 内或在数个 list 间添加.移除和移动元素不会非法化迭代器或引用.迭代器

C++ std::deque 基本用法

#include <iostream> #include <string> #include <deque> // https://zh.cppreference.com/w/cpp/container/deque // vector 和 deque 的差别 // https://www.cnblogs.com/zhuyf87/archive/2012/12/09/2809896.html using namespace std; int main() { int a[

std::back_inserter函数用法

back_inserter函数:配合copy函数,把[a, b)区间的数据插入到string对象的末尾,如果容量不够,动态扩容. 使用案例: 1.客户端与服务器通信场景:服务器向客户端发送数据,客户端接收数据. 接收数据的三种方法: (1)错误方法:把接收到的c风格字符串用string构造函数转成string对象,再利用string的重载加运算符函数拼接到变量末尾.数据很有可能是不以'\0'结尾,这样的话将出现严重bug. (2)低效率方法:一个字符一个字符的追加. (3)正确高效方法:运用co