`

C++标准库笔记二:STL迭代器和STL函数对象

 
阅读更多

 

下面的代码用gcc version 3.4.5 (mingw-vista special r3)测试

来源于sgi STL的官方手册以及《泛型编程与STL》(Generic Programming and the STL)

 

 

// 编译命令行:
// g++ test005.cpp

// 演示STL迭代器
#include <list>
#include <vector>
#include <string>
#include <iterator>
#include <iostream>

class Int 
{
public:
	Int(int x):val(x) 
	{
	
	}
	int get() 
	{ 
		return val; 
	}
private:
	int val;
};    

int main(int argc, const char *argv[])
{
	{
		//front_insert_iterator<FrontInsertionSequence>,用于从前面依次插入元素
		std::list<int> L;
		L.push_front(3);
		std::front_insert_iterator< std::list<int> > ii(L);
		*ii++ = 0;
		*ii++ = 1;
		*ii++ = 2;
		//输出2 1 0 3
		std::copy(L.begin(), L.end(), 
			std::ostream_iterator<int>(std::cout, " "));
		std::cout << std::endl;
	}
	
	{
		//back_insert_iterator<BackInsertionSequence>,用于从后面依次插入元素
		//效果相当于
		//copy(L.begin(), L.end(), back_inserter(v2));
		//也相当于更快的方法(如果原来没有元素的话)
		//vector v1(L.begin(), L.end());
		std::list<int> L;
		L.push_front(3);
		std::back_insert_iterator< std::list<int> > ii(L);
		*ii++ = 0;
		*ii++ = 1;
		*ii++ = 2;
		// 输出3 0 1 2
		std::copy(L.begin(), L.end(), 
			std::ostream_iterator<int>(std::cout, " "));
		std::cout << std::endl;
	}
	
	{
		//insert_iterator<Container>,用于某个位置后面的空挡处插入元素
		std::list<int> L;
		L.push_front(3);
		std::insert_iterator< std::list<int> > ii(L, L.begin());
		*ii++ = 0;
		*ii++ = 1;
		*ii++ = 2;
		std::copy(L.begin(), L.end(), 
			std::ostream_iterator<int>(std::cout, " "));
		std::cout << std::endl;
	}
	
	//if(false)
	{
		//istream_iterator<T, Distance> / ostream_iterator<T>,用于把输入/输出流转换为迭代器
		fflush(stdin);
		std::vector<int> V;
		std::cout << "please input some number (. to end)" << std::endl;
		std::copy(std::istream_iterator<int>(std::cin), 
			std::istream_iterator<int>(),
			std::back_inserter(V)); 
		std::copy(V.begin(), V.end(), 
			std::ostream_iterator<int>(std::cout, "\n"));
		fflush(stdout);
	}
	
	//if(false)
	{
		//istreambuf_iterator / ostreambuf_iterator,用于把输入/输出流缓冲转换为迭代器
		fflush(stdin);
		std::istreambuf_iterator<char> first(std::cin);
		std::istreambuf_iterator<char> eos;
		std::cout << "please input string (Ctrl+Z to end)" << std::endl;
		std::vector<char> buffer(first, eos);
		std::copy(buffer.begin(), buffer.end(),
			std::ostreambuf_iterator<char>(std::cout));
		std::cout << std::endl;
		fflush(stdout);
	}
	
	{
		//reverse_iterator<RandomAccessIterator, T, Reference, Distance>,用于作为参数传入算法时,颠倒容器的前后次序
		std::string s = "This is a test.";
		std::copy(std::reverse_iterator<std::string::iterator>(s.end()),
			std::reverse_iterator<std::string::iterator>(s.begin()),
			std::ostream_iterator<char>(std::cout));
		std::cout << std::endl;
	}
	
	{
		//raw_storage_iterator<ForwardIterator, T>,和迭代器类似,但使用已经分配的内存而非用new分配。
		//在不分配内存的情况下只调用构造函数,即*r = x等效于construct(&*i, x).
		int A1[] = {1, 2, 3, 4, 5, 6, 7};
		const int N = sizeof(A1) / sizeof(int);
		Int* A2 = (Int*) malloc(N * sizeof(Int));     
		std::transform(A1, A1 + N, 
			std::raw_storage_iterator<Int*, int>(A2),
			std::negate<int>());
		for(int i = 0; i < N; i++)
		{
			std::cout << "A2[" << i << "] == " << A2[i].get() << std::endl;
		}
		std::cout << std::endl;
		free(A2);
	}
	
	//标准C++允许main不返回,但标准C要求必须返回
	return 0;
}

 

 

 

// 编译命令行:
// g++ test006.cpp

// 演示STL函数对象
#include <math.h>
#include <assert.h>
#include <vector>
#include <list>
#include <map>
#include <iostream>
#include <iterator>
#include <functional>
// for iota / transform
#include <ext/numeric>
// for hash, or #include <ext/hash_set>
#include <ext/hash_map>

struct sine:public std::unary_function<double, double> 
{
    double operator()(double x) 
    { 
		return sin(x); 
	}
};

struct exponentiate : public std::binary_function<double, double, double> 
{
    double operator()(double x, double y) 
    { 
		return pow(x, y); 
	}
};


struct B 
{
	virtual void print() = 0;
};

struct D1 : public B 
{
	void print() 
	{ 
		std::cout << "I'm a D1" << std::endl; 
	}
};

struct D2 : public B 
{
	void print() 
	{ 
		std::cout << "I'm a D2" << std::endl; 
	}
};

struct Operation 
{
	virtual double eval(double) = 0;
};

struct Square : public Operation 
{
	double eval(double x) 
	{ 
		return x * x; 
	}
};

struct Negate : public Operation 
{
	double eval(double x) 
	{ 
		return -x; 
	}
};

int main(int argc, const char *argv[])
{
	{
		//unary_function<Arg, Result>,用于作为基类声明一元函数对象(一元仿函数,实际上是个类)
		//binary_function<Arg1, Arg2, Result>,用于作为基类声明二元函数对象
		
	}
	
	{
		//plus<T> / minus<T> / multiplies<T> / divides<T> / modulus<T>,
		//序列相加/相减/相乘/相除/取模
		//V3 = V1 + V2
		const int N = 1000;
		std::vector<double> V1(N);
		std::vector<double> V2(N);
		std::vector<double> V3(N);
		__gnu_cxx::iota(V1.begin(), V1.end(), 1);
		std::fill(V2.begin(), V2.end(), 75);
		assert(V2.size() >= V1.size() && V3.size() >= V1.size());
		std::transform(V1.begin(), V1.end(), V2.begin(), V3.begin(),
			std::plus<double>());
	}
	
	{
		//negate<T>,序列取相反数
		//V2 = -V1
		const int N = 1000;
		std::vector<int> V1(N);
		std::vector<int> V2(N);
		__gnu_cxx::iota(V1.begin(), V1.end(), 1);
		assert(V2.size() >= V1.size());
		std::transform(V1.begin(), V1.end(), V2.begin(),
			std::negate<int>());
	}
	
	{
		//equal_to<T> / not_equal_to<T> / less<T> / greater<T> / less_equal<T> / greater_equal<T>
		//条件操作,判断是否等于/不等于/小于/大于/小于等于/大于等于某个数
		int A[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0};
		const int N = sizeof(A)/sizeof(int);
		//把0移到最左边的区间
		std::partition(A, A + N,
			std::bind2nd(std::equal_to<int>(), 0));
		std::copy(A, A + N, 
			std::ostream_iterator<int>(std::cout, " "));
		std::cout << std::endl;

		std::list<int> L(1000);
		std::fill(L.begin(), L.end(), 75);
		//查找满足条件的位置
		std::list<int>::iterator first_nonzero = 
			std::find_if(L.begin(), L.end(), 
				std::bind2nd(std::not_equal_to<int>(), 0));
		assert(first_nonzero == L.end() || *first_nonzero != 0);
	}
	
	{
		//logical_and<T> / logical_or<T> / logical_not<T>
		//条件操作,判断两个条件的与/或/非
		std::list<int> L;
		std::fill(L.begin(), L.end(), 75);
		std::list<int>::iterator in_range = 
			std::find_if(L.begin(), L.end(),
				__gnu_cxx::compose2(std::logical_and<bool>(),
					std::bind2nd(std::greater_equal<int>(), 1),
					std::bind2nd(std::less_equal<int>(), 10)));
		assert(in_range == L.end() || (*in_range >= 1 && *in_range <= 10));
		
		char str[] = "Hello world!";
		const int MAXLEN = sizeof(str) / sizeof(char);
		const char* wptr = 
			std::find_if(str, str + MAXLEN,
				__gnu_cxx::compose2(std::logical_or<bool>(),
					std::bind2nd(std::equal_to<char>(), ' '),
					std::bind2nd(std::equal_to<char>(), '\n')));
		assert(wptr == str + MAXLEN || *wptr == ' ' || *wptr == '\n');
	
		std::vector<bool> V;
		V.push_back(true);
		V.push_back(false);
		std::transform(V.begin(), V.end(), V.begin(), 
			std::logical_not<bool>());
	}
	
	{
		//identity<T>,原值返回
		int x = 137;
		__gnu_cxx::identity<int> id;
		assert(x == id(x));
	}
	
	{
		//project1st<Arg1, Arg2>,忽略第二参数
		std::vector<int> v1(10, 137);
		std::vector<char*> v2(10, (char*) 0);
		std::vector<int> result(10);
		std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(),
			__gnu_cxx::project1st<int, char*>());
		assert(std::equal(v1.begin(), v1.end(), result.begin()));
	}
	
	{
		//project2nd<Arg1, Arg2>,忽略第一参数
		std::vector<char*> v1(10, (char*) 0);
		std::vector<int> v2(10, 137);
		std::vector<int> result(10);
		std::transform(v1.begin(), v1.end(), v2.begin(), result.begin(),
			__gnu_cxx::project2nd<char*, int>());
		assert(std::equal(v2.begin(), v2.end(), result.begin()));
	}
	
	{
		//select1st<Pair>,pair或pair相同接口(如map)的类的第一参数
		//select2nd<Pair>,pair或pair相同接口(如map)的类的第二参数
		std::map<int, double> M;
		M[1] = 0.3;
		M[47] = 0.8;
		M[33] = 0.1;
		// 输出1 33 47.
		std::transform(M.begin(), M.end(), 
			std::ostream_iterator<int>(std::cout, " "),
			__gnu_cxx::select1st<std::map<int, double>::value_type>());
		std::cout << std::endl;
		// 输出0.3 0.1 0.8
		std::transform(M.begin(), M.end(), 
			std::ostream_iterator<double>(std::cout, " "),
			__gnu_cxx::select2nd<std::map<int, double>::value_type>());
		std::cout << std::endl;
	}
	
	{
		//hash<T>,返回哈希值
		__gnu_cxx::hash<const char*> H;
		std::cout << "foo -> " << H("foo") << std::endl;
		std::cout << "bar -> " << H("bar") << std::endl;
	}
	
	{
		//subtractive_rng,伪随机数生成器,减去法
		__gnu_cxx::subtractive_rng R;
		//生成0至4之间的伪随机数
		for (int i = 0; i < 20; ++i)
			std::cout << R(5) << ' ';
		std::cout << std::endl;
	}
	
	{
		//mem_fun_t<Result, X>,用于遍历调用多态的虚函数,容器元素是指针
		//mem_fun1_t<Result, X, Arg>,传入容器的元素作为参数,遍历调用多态的虚函数,容器元素是指针
		//const_mem_fun_t / const_mem_fun1_t,用于const的成员函数,用法类似 
		std::vector<B*> V;
		V.push_back(new D1);
		V.push_back(new D2);
		V.push_back(new D2);
		V.push_back(new D1);
		std::for_each(V.begin(), V.end(), 
			std::mem_fun(&B::print));
		
		std::vector<Operation*> operations;
		std::vector<double> operands;
		operations.push_back(new Square);
		operations.push_back(new Square);
		operations.push_back(new Negate);
		operations.push_back(new Negate);
		operations.push_back(new Square);
		operands.push_back(1);
		operands.push_back(2);
		operands.push_back(3);
		operands.push_back(4);
		operands.push_back(5);
		std::transform(operations.begin(), operations.end(),
			operands.begin(),
			std::ostream_iterator<double>(std::cout, "\n"),
			std::mem_fun(&Operation::eval));
	}
	
	{
		//mem_fun_ref_t<Result, X>,用于遍历调用多态的虚函数,容器元素是引用
		//mem_fun1_ref_t<Result, X, Arg>,传入容器的元素作为参数,遍历调用多态的虚函数,容器元素是引用
		//const_mem_fun_ref_t / const_mem_fun1_ref_t,用于const的成员函数,用法类似
		std::vector<D1> V;
		V.push_back(D1());
		V.push_back(D1());
		std::for_each(V.begin(), V.end(), 
			std::mem_fun_ref(&B::print));
			
		int A1[5] = {1, 2, 3, 4, 5};
		int A2[5] = {1, 1, 2, 3, 5};
		int A3[5] = {1, 4, 1, 5, 9};
		std::vector<std::vector<int> > V2;
		V2.push_back(std::vector<int>(A1, A1 + 5));
		V2.push_back(std::vector<int>(A2, A2 + 5));
		V2.push_back(std::vector<int>(A3, A3 + 5));
		int indices[3] = {0, 2, 4};
		int& (std::vector<int>::*extract)(std::vector<int>::size_type);
		//使用&,否则编译器报错
		//输出1 2 9
		extract = &std::vector<int>::operator[];
		std::transform(V2.begin(), V2.end(), indices,
			std::ostream_iterator<int>(std::cout, "\n"),
			std::mem_fun_ref(extract));
	}
	
	{
		//binder1st<AdaptableBinaryFunction>,用于把第一参数设为常数
		std::list<int> L;
		std::fill(L.begin(), L.end(), 75);
		std::list<int>::iterator first_nonzero = 
			std::find_if(L.begin(), L.end(), 
				std::bind1st(std::not_equal_to<int>(), 0));
		assert(first_nonzero == L.end() || *first_nonzero != 0);
	}
	
	{
		//binder2nd<AdaptableBinaryFunction>,用于把第二参数设为常数
		std::list<int> L;
		std::fill(L.begin(), L.end(), 75);
		std::list<int>::iterator first_positive = 
			std::find_if(L.begin(), L.end(), 
				std::bind2nd(std::greater<int>(), 0));
		assert(first_positive == L.end() || *first_positive > 0);
	}
	
	{
		//pointer_to_unary_function<Arg, Result>,用于把一个参数的C函数转为函数对象,
		//pointer_to_binary_function<Arg1, Arg2, Result>,同上,把两个参数的C函数转为函数对象
		//常用于叠加的函数对象如compose1,
		//如果没有叠加,可以直接使用C函数如fabs,则不需要std::ptr_fun()的辅助
		const int N = 1000;
		std::vector<double> V1(N);
		__gnu_cxx::iota(V1.begin(), V1.end(), 1);
		//如果出现错误:
		//error: expected primary-expression before ',' token
		//请检查函数对象如std::negate<double>()后面的括号是否遗漏
		//
		//直接使用fabs时不需要使用ptr_fun
		//std::transform(V1.begin(), V1.end(), V1.begin(), fabs);
		//
		std::transform(V1.begin(), V1.end(), V1.begin(),
			__gnu_cxx::compose1(std::negate<double>(), std::ptr_fun(fabs)));
			
		//使用两个参数C函数strcmp进行条件查找
		char *str = "OK";
		const int N2 = 1000;
		std::list<char*> L(N2);
		//使用fill之前需要小心容器的个数(需要在创建时指定,而非缺省)
		std::fill(L.begin(), L.end(), str);
		//如果出现这样的错误
		//error: missing template arguments before '(' token
		//提示binder2nd缺少模板参数,
		//可以输入一个错误的模板参数类型,如<int>
		//然后看错误提示
		assert(!strcmp(L.front(), str));
		//
		//查找第一个等于"OK"的位置
		//
		std::list<char*>::iterator item = 
			std::find_if(L.begin(), L.end(),
				std::not1(
					std::binder2nd< std::pointer_to_binary_function<const char*, const char*, int> >(
						std::ptr_fun(strcmp), "OK")));
		assert(!strcmp(*item, "OK"));
		assert(item == L.end() || strcmp(*item, "OK") == 0);
	}
	
	{
		//unary_negate<AdaptablePredicate>,用于一元函数逻辑非
		//binary_negate<AdaptableBinaryPredicate>,用于二元函数的逻辑非
		const int N = 1000;
		std::list<int> L(N);
		std::fill(L.begin(), L.end(), 75);
		std::list<int>::iterator in_range = 
			std::find_if(L.begin(), L.end(),
				std::not1(
					__gnu_cxx::compose2(std::logical_and<bool>(),
						std::bind2nd(std::greater_equal<int>(), 1),
						std::bind2nd(std::less_equal<int>(), 10))));
		assert(in_range == L.end() || !(*in_range >= 1 && *in_range <= 10));
		
		char str[] = "Hello, world!";
		const int MAXLEN = sizeof(str) / sizeof(char);
		const char* wptr = find_if(str, str + MAXLEN,
			__gnu_cxx::compose2(std::not2(std::logical_or<bool>()),
				std::bind2nd(std::equal_to<char>(), ' '),
				std::bind2nd(std::equal_to<char>(), '\n')));
		assert(wptr != str + MAXLEN);
		assert(wptr == str + MAXLEN || !(*wptr == ' ' || *wptr == '\n')); 
	}
	
	{
		//unary_compose<AdaptableUnaryFunction1,AdaptableUnaryFunction2>
		//用于把两个一元函数f(x),g(x)组合成f(g(x))
		//binary_compose<AdaptableBinaryFunction,AdaptableUnaryFunction1,AdaptableUnaryFunction2>
		//用于把两个二元函数f(x),g(x)组合成f(g(x))
		std::vector<double> angles;
		std::vector<double> sines(100);
		const double pi = 3.14159265358979323846;
		for(int i = 0; i <90; i++)
		{
			angles.push_back(i);
		}
		assert(sines.size() >= angles.size());
		std::transform(angles.begin(), angles.end(), sines.begin(),
			__gnu_cxx::compose1(std::negate<double>(),
				__gnu_cxx::compose1(std::ptr_fun(sin),
					std::bind2nd(std::multiplies<double>(), pi / 180.))));
		
		std::list<int> L(100);
		std::fill(L.begin(), L.end(), 75);
		std::list<int>::iterator in_range = 
			std::find_if(L.begin(), L.end(),
				__gnu_cxx::compose2(std::logical_and<bool>(),
					std::bind2nd(std::greater_equal<int>(), 1),
					std::bind2nd(std::less_equal<int>(), 10)));
		assert(in_range == L.end() || (*in_range >= 1 && *in_range <= 10));
		
		std::list<double> L2(100);
		std::fill(L2.begin(), L2.end(), 75.0);
		double DBL_MIN = 1.0;
		//计算sin(x)/(x + DBL_MIN)
		std::transform(L2.begin(), L2.end(), L2.begin(),
			__gnu_cxx::compose2(std::divides<double>(),
				std::ptr_fun(sin),
				std::bind2nd(std::plus<double>(), DBL_MIN)));
	}
	
	//标准C++允许main不返回,但标准C要求必须返回
	return 0;
}
分享到:
评论

相关推荐

    侯捷STL课件_C++_候捷课件stl_c++侯捷课件_

    STL,全称Standard Template Library,是C++编程语言中的一个核心组件,由Alexander Stepanov和Mangus Sander等人设计,为程序员提供了高效且灵活的容器、迭代器、算法和函数对象等工具。侯捷,作为知名的C++专家,...

    C++ STL 上课笔记

    在这份“C++ STL 上课笔记”中,我们将深入探讨STL的各个关键组成部分,包括容器、迭代器、算法和函数对象。 1. **容器** STL提供了多种容器来存储和管理数据。例如: - **vector**: 动态数组,支持快速随机访问...

    C++进阶STL笔记资料.zip

    三、STL迭代器 迭代器是STL的桥梁,它像指针一样遍历容器中的元素,但提供了更丰富的操作。迭代器分为输入迭代器、输出迭代器、前向迭代器、双向迭代器和随机访问迭代器五种类型,分别对应不同的操作能力。 四、STL...

    C++进阶STL源码笔记

    在C++编程中,STL(Standard Template Library,标准模板库)是不可或缺的一部分,它为开发者提供了高效且灵活的数据结构和算法。这份“C++进阶STL源码笔记”显然是一个深入研究STL的资源,适合那些已经有一定C++...

    C++笔记、常用函数、STL

    STL是C++标准库的核心部分,它提供了一组高效的容器(如`std::vector`、`std::list`、`std::map`等)、迭代器、算法和函数对象。这些组件可以组合使用,实现各种复杂的数据结构和算法。 1. 容器:容器是STL中用于...

    C++STL学习笔记.pdf

    STL的主要组成部分包括容器(containers)、迭代器(iterators)、算法(algorithms)、仿函数(functors)和适配器(adapters)。 首先,容器用于存储数据,并提供了遍历、插入和删除等操作。STL容器主要分为序列...

    c++ -- stl 学习笔记

    首先,STL的核心概念是容器、迭代器、算法和函数对象。容器是STL提供的一系列数据结构,如vector(动态数组)、list(双向链表)、set(红黑树实现的集合)和map(键值对映射)。它们为存储和管理数据提供了不同的...

    C++/STL/读书笔记

    C++/STL/读书笔记是对C++标准模板库(Standard Template Library,简称STL)深入学习的重要资源。STL是C++编程中不可或缺的一部分,它提供了高效且可重用的数据结构和算法,极大地提高了代码的编写效率和可读性。...

    C++基础笔记,到STL库

    9. **STL(Standard Template Library)**:STL是C++标准库的一部分,提供了容器(如vector、list、map等)、迭代器、算法和函数对象等组件,极大提高了代码的可读性和复用性。 10. **C++新特性**:随着标准的更新,...

    STL标准模板库笔记

    C++ STL(Standard Template Library,标准模板库)是一组广泛使用的C++编程语言模板,它包含了各种通用数据结构和算法的实现。STL允许程序员不必从零开始就能实现复杂的数据处理和操作,其主要组成部分包括容器、...

    C++ Standard template Library英文版和Effective STL中文版

    C++ Standard Template Library (STL) 是C++编程语言中不可或缺的一部分,它提供了一组高效、可重用的容器、迭代器、算法和函数对象。STL的核心思想是泛型编程,即通过模板来实现代码的复用,使得开发者可以处理不同...

    《Effective STL》学习笔记

    1. **STL的五大组件**:STL主要由五大组件构成,包括容器(如vector、list、set等)、迭代器、算法、函数对象和适配器。理解它们的功能和相互关系是使用STL的基础。 2. **迭代器的使用和理解**:迭代器是STL中的...

    千锋C++笔记.zip

    10. **STL(Standard Template Library)**:STL是C++的标准库,包含容器(如vector、list、set、map等)、算法(如排序、查找等)、迭代器和内存管理工具(如智能指针),极大提高了编程效率。 11. **I/O流库**:...

    effective c++读书笔记

    - STL(标准模板库):STL是一个包含容器、迭代器、算法和函数对象的模板库,它提供了一组通用的、经过优化的数据结构和算法实现。 2. 用const、enum和inline替代#define:这一部分强调了使用预处理器宏的缺点,...

    c++个人学习笔记归纳总结.rar_C++STL_X9H3_c++个人笔记总结

    在C++编程领域,STL(Standard Template Library,标准模板库)是不可或缺的一部分,它极大地提高了程序员的效率,提供了高效且可重用的数据结构和算法。以下是对标题、描述及标签所涉及知识点的详细说明: 一、C++...

    C++语言 STL学习笔记.pdf

    C++中的标准模板库(STL)是一个强大的库,它包含了一系列的数据结构和算法。本次学习笔记将围绕STL中的一些容器和函数进行详细探讨,包括vector、set、string和map等常用容器的定义、操作方法和它们的常见用途。 ...

    精版Effective STL读书笔记

    整体而言,Finix的精版《Effective STL》读书笔记覆盖了STL的关键知识点,包括各种容器的特性、迭代器的使用、以及如何高效地操作和管理容器。这对于任何想要深入了解并有效应用STL的C++程序员来说,都是宝贵的资源...

    面向对象程序设计C++听课笔记

    4. STL(Standard Template Library):C++的标准模板库,包含容器(如vector、list)、算法和迭代器等。 七、异常处理 1. 异常处理机制:在程序运行时捕获和处理错误,避免程序异常终止。 2. throw和catch关键字:...

    C++笔记.rar C++笔记.rar

    5. **STL(Standard Template Library)**:STL是C++的标准库,包含容器(如vector、list、set等)、迭代器、算法和函数对象,为程序员提供了高效的数据结构和算法。 6. **异常处理**:C++提供了异常处理机制,通过...

    STLSourceAnalysis:stl原始码剖析(侯捷)的学习笔记

    STL,全称为Standard Template Library,是C++标准库中的一个重要组成部分,主要包含容器、迭代器、算法和函数对象等组件。《STL源码剖析》是著名C++专家侯捷的一部经典著作,深入解析了STL的内部实现机制,帮助读者...

Global site tag (gtag.js) - Google Analytics