模拟实现STL库
最近在复习STL,感觉再看的时候比刚开始学的时候通透很多。以前模拟实现了一个STL库,最近复习完又重构了一遍。代码放出来以供后面学习。如果有写的不好的地方欢迎大家批评指正。
STL_List.h
#pragma once
#include"STL_Iterator.h" template<class T>
struct _List_Node
{
_List_Node* _prev;
_List_Node* _next;
T _data;
_List_Node()
{ }
_List_Node(const T& x)
:_data(x)
, _prev(NULL)
, _next(NULL)
{ }
}; template<class T, class Ref, class Ptr>
struct _List_Iterator
{
typedef BidirectionalIterator_tag IteratorCategory;
typedef _List_Iterator<T, T&, T*> Iterator;
typedef T ValueType;
typedef T& Reference;
typedef T* Pointer;
typedef _List_Node<T> *LinkType;
typedef _List_Iterator<T, Ref, Ptr> Self;
typedef int DifferenceType;
LinkType _node; _List_Iterator()
{ }
_List_Iterator(LinkType x)
:_node(x)
{
}
Reference operator*()
{
return _node->_data;
}
Pointer operator->()
{
return &(_node->_data);
}
Iterator operator++()
{
_node = _node->_next;
return *this;
}
Iterator operator++(int)
{
Iterator tmp;
tmp = *this;
_node = _node->_next;
return tmp;
} Iterator operator--()
{
_node = _node->_prev;
return *this;
}
Iterator operator--(int)
{
Iterator tmp = *this;
_node = _node->_prev;
return tmp;
} bool operator!=(const Self& x)
{
return _node != x._node;
} bool operator==(const Self& x)
{
return _node == x._node;
} }; template<class T, class Alloc = Alloc>
class List
{
public:
typedef _List_Node<T>* LinkType;
typedef _List_Iterator<T, T&, T*> Iterator;
typedef SimpleAlloc<_List_Node<T>, Alloc> ListNodeAllocator; List()
{
_node = new _List_Node<T>();
_node->_next = _node;
_node->_prev = _node;
}
~List()
{
Destory(Begin(), End());
Iterator it = Begin();
while (it != End())
{
ListNodeAllocator::Deallocate(it._node);
}
} Iterator Begin()
{
return _node->_next;
} Iterator End()
{
return _node;
} Iterator Insert(Iterator pos, const T& x)
{
LinkType prev = pos._node->_prev;
LinkType tmp = ListNodeAllocator::Allocate();
Construct(tmp, x);
//LinkType tmp = new _List_Node<T>(x);
prev->_next = tmp;
pos._node->_prev = tmp;
tmp->_next = pos._node;
tmp->_prev = prev;
return tmp;
} void PushBack(const T& x)
{
Insert(End(), x);
} void PushFront(const T& x)
{
Insert(Begin, x);
} //reverse
//remove
//empty
//size
//unique
//merge
protected:
LinkType _node;
}; void TestList()
{
List<int> l;
l.PushBack();
l.PushBack();
l.PushBack();
l.PushBack();
l.PushBack(); List<int>::Iterator it;
List<int>::Iterator begin = l.Begin();
List<int>::Iterator end = l.End();
for (it = l.Begin(); it != l.End(); it++)
{
cout << *it << " ";
}
cout << "Distance" << Distance(begin, end) << endl;
}
STL_Vector.h
#pragma once
#include<cassert>
#include"STL_Iterator.h"
#include"STL_Alloc.h"
#include"STL_Construct.h"
#include"STL_Uninittialized.h" template<class T, class Alloc = Alloc>
class Vector
{
typedef T ValueType;
typedef T& Reference;
typedef T* Pointer;
typedef int DifferenceType;
public:
typedef ValueType * Iterator;
typedef RandomAccessIterator_tag IteratorCategory;
typedef SimpleAlloc<T, Alloc> DataAlloc; Iterator Begin() { return Start; }
Iterator End() { return Finish; } Vector()
:Start(NULL)
, Finish(NULL)
, EndOfStorage(NULL)
{ }
Vector(size_t n, const T& value)
{
Start = new T[n];
Finish = Start + n;
EndOfStorage = Finish;
}
~Vector()
{
Destory(Start, Finish);
DataAlloc::Deallocate(Start, Size());
} /*void Insert(Iterator Position,size_t n,const ValueType& x)
{
if (n != 0)
{
if (size_t(EndOfStorage - Finish) > n)
{
size_t Elems_After = Finish - Position;
Iterator OldFinish = Finish;
if (Elems_After > n)
{
Finish += n;
Copy_Backward(Position, OldFinish - n, OldFinish);
while (n-- > 0)
{
*(Position++) = x;
}
}
else
{
int tmp = n - Elems_After;
while (tmp-- > 0)
{
*(Finish++) = x;
}
tmp = OldFinish - Position;
for (int i = 0; i < tmp; ++i)
{
*(Finish++) = *(Position + i);
}
while (n-- > 0)
{
*(Position++) = x;
}
}
}
else
{
ExpandCapacity();
Insert(Position, n, x);
}
}
}*/
void Push_Back(const T& x)
{
ExpandCapacity();
Construct(Finish, x);
Finish++; }
void Pop_Back()
{
assert(Size());
Destory(Finish);//ÓбØҪô£¿£¿
--Finish;
}
size_t Size()
{
return (Finish - Start);
} bool Empty()
{
return Beign == End;
} Iterator Erase(Iterator pos)
{
Iterator begin = pos;
wihle(begin + != Finish)
{
*begin = *(beign + );
}
--Finish;
return pos;
} protected: void Copy_Backward(Iterator Position, Iterator first, Iterator last)
{
while (first != Position - )
{
*(last--) = *(first--);
} }
void ExpandCapacity()
{
if (Finish == EndOfStorage)
{
size_t size = Size();
size_t curLength = EndOfStorage - Start;
size_t newLength = * curLength + ;
T *tmp = DataAlloc::Allocate(newLength);
if (Start)
{
UninitializedCopy(Start, Start + size, tmp);
}
Destory(Start, Finish);
DataAlloc::Deallocate(Start, EndOfStorage - Start); Start = tmp;
Finish = Start + Size();
EndOfStorage = Start + newLength; /* Iterator newStart = new T[newLength];
Iterator it = Begin();
for (int i = 0; i < Size(); ++i)
{
newStart[i] = Start[i];
}
Destory();
Start = newStart;
Finish = Start + curLength;
EndOfStorage = Start + newLength;*/
}
}
//void Destory()
//{
// delete[] Start;
// Start = NULL;
// Finish = NULL;
// EndOfStorage = NULL;
//}
protected:
Iterator Start;
Iterator Finish;
Iterator EndOfStorage;
}; void TestVector()
{
Vector<int> v;
v.Push_Back();
v.Push_Back();
v.Push_Back();
v.Push_Back();
v.Push_Back();
Vector<int>::Iterator cur;
for (cur = v.Begin(); cur != v.End(); cur++)
{
cout << *cur << " ";
}
}
- 数组是将元素在内存中连续存放,由于每个元素占用内存相同,可以通过下标迅速访问数组中任何元素。但是如果要在数组中增加一个元素,需要移动大量元素,在内存中空出一个元素的空间,然后将要增加的元素放在其中。同样的道理,如果想删除一个元素,同样需要移动大量元素去填掉被移动的元素。如果应用需要快速访问数据,很少或不插入和删除元素,就应该用数组。
- 链表恰好相反,链表中的元素在内存中不是顺序存储的,而是通过存在元素中的指针联系到一起。比如:上一个元素有个指针指到下一个元素,以此类推,直到最后一个元素。如果要访问链表中一个元素,需要从第一个元素开始,一直找到需要的元素位置。但是增加和删除一个元素对于链表数据结构就非常简单了,只要修改元素中的指针就可以了。如果应用需要经常插入和删除元素你就需要用链表数据结构了。
STL_Uninitialized.h
#pragma once
#include"STL_Iterator.h"
#include"TypeTraits.h"
#include"STL_Construct.h"
#include"STL_Iterator.h"
#include<memory.h> template <class InputIterator, class ForwardIterator>
inline ForwardIterator
__UninitializedCopyAux(InputIterator first, InputIterator last,
ForwardIterator result,
__TrueType) {
return copy(first, last, result);
} template <class InputIterator, class ForwardIterator>
ForwardIterator
__UninitializedCopyAux(InputIterator first, InputIterator last,
ForwardIterator result,
__FalseType) {
ForwardIterator cur = result; for (; first != last; ++first, ++cur)
Construct(&*cur, *first);
return cur;
} template <class InputIterator, class ForwardIterator, class T>
inline ForwardIterator __UninitializedCopy(InputIterator first, InputIterator last,
ForwardIterator result, T*)
{
typedef typename __TypeTraits<T>::IsPODType IsPOD;
return __UninitializedCopyAux(first, last, result, IsPOD());
} template <class InputIterator, class ForwardIterator>
inline ForwardIterator UninitializedCopy(InputIterator first, InputIterator last,
ForwardIterator result) {
return __UninitializedCopy(first, last, result, ValueType(result));
} inline char* UninitializedCopy(const char* first, const char* last,
char* result) {
memmove(result, first, last - first);
return result + (last - first);
} inline wchar_t* UninitializedCopy(const wchar_t* first, const wchar_t* last,
wchar_t* result) {
memmove(result, first, sizeof(wchar_t)* (last - first));
return result + (last - first);
}
STL_Construct.h
#pragma once #include"TypeTraits.h" template<class T>
inline void Destory(T *pointer)
{
pointer->~T();
} template<class T1, class T2>
inline void Construct(T1 *p, const T2& value)
{
new(p)T1(value);
} template<class ForwardIterator>
inline void __DestoryAux(ForwardIterator first, ForwardIterator last, __FalseType)
{
for (; first < last; ++first)
{
Destory(&*first);
}
} template<class ForwardIterator>
inline void __DestoryAux(ForwardIterator first, ForwardIterator last, __TrueType)
{} template<class ForwardIterator, class T>
inline void __Destory(ForwardIterator first, ForwardIterator last, T *)
{
typedef typename __TypeTraits<T>::HasTrivialDestructor TrivialDestructor;
__DestoryAux(first, last, TrivialDestructor());
} template<class ForwardIterator>
inline void Destory(ForwardIterator first, ForwardIterator last)
{
__Destory(first, last, ValueType(first));
} inline void Destory(char*, char*) {}
inline void Destory(wchar_t*, wchar_t*) {}
STL_Alloc.h
#pragma once template<class T, class Alloc>
class SimpleAlloc
{
public:
static T *Allocate(size_t n)
{
return == n ? : (T*)Alloc::Allocate(n * sizeof(T));
}
static T *Allocate(void)
{
return (T*)Alloc::Allocate(sizeof(T));
}
static void Deallocate(T *p, size_t n)
{
if ( != n) Alloc::Deallocate(p, n * sizeof(T));
}
static void Deallocate(T *p)
{
Alloc::Deallocate(p, sizeof(T));
}
}; template<int inst>
class __MallocAllocTemplate//一级配置器
{
private:
static void *OomMalloc(size_t n)
{
void(*MyMallocHandler)();//期待可以通过用户设置的handler解决内存不足问题(释放一部分内存)
void *result; while ()
{
MyMallocHandler = __MallocAllocOomHandler;
if ( == MyMallocHandler)
{
cout << "别开辟了,实在没有了(此处应该抛出异常)" << endl;
exit(-);
}
(*MyMallocHandler)();
result = malloc(n);
if (result) return(result);
}
}
static void *OomRealloc(void *ptr, size_t n)
{
void(*MyMallocHandler)();//期待可以通过用户设置的handler解决内存不足问题(释放一部分内存)
void *result; while ()
{
MyMallocHandler = __MallocAllocOomHandler;
if ( == MyMallocHandler)
{
cout << "别开辟了,实在没有了(此处应该抛出异常)" << endl;
exit(-);
}
(*MyMallocHandler)();
result = realloc(p, n);
if (result) return(result);
}
}
static void(*__MallocAllocOomHandler)();//定义函数指针,其实没啥用
public:
static void *Allocate(size_t n)
{
void *result = malloc(n);
if ( == result)
{
result = OomMalloc(n);
}
return result;
}
static void Deallocate(void *p, size_t n)//后面的n似乎用处不大
{
free(p);
}
static void *Reallocate(void *p, size_t oldsize, size_t newsize)
{
void *result = realloc(p, newsize);
if ( == result)
{
result = OomRealloc(p, newsize);
}
return result;
}
static void(*SetMallocHandler(void(*f)()))()
{
void(*old)() = __MallocAllocOomHandler;
__MallocAllocOomHandler = f;
return(old);//设置新的处理函数指针,返回旧的函数指针
} };
template <int inst>
void(*__MallocAllocTemplate<inst>::__MallocAllocOomHandler)() = ;//所以说那个函数指针一般没啥用都设为NULL了 typedef __MallocAllocTemplate<> MallocAlloc; # ifdef __USE_MALLOC typedef malloc_alloc Alloc;
# else template<bool threads, int inst>
class __DefaultAllocTemplate//二级空间配置器含有内存池
{
enum { __ALIGN = };
enum { __MAX_BYTES = };
enum { __NFREELISTS = __MAX_BYTES / __ALIGN };
private: static size_t ROUND_UP(size_t bytes) {
return (((bytes)+__ALIGN - ) & ~(__ALIGN - ));
}
union Obj {
union Obj * FreeListLink;
char ClientData[]; /* The client sees this. */
}; static Obj * volatile FreeList[__NFREELISTS];//声明自由链表
static char *StartFree;
static char *EndFree;
static size_t HeapSize; static size_t FREELIST_INDEX(size_t bytes) {
return (((bytes)+__ALIGN - ) / __ALIGN - );
} static void *Refill(size_t n)
{
int nobjs = ;
char *chunk = ChunkAlloc(n, nobjs);
Obj* volatile MyFreeList;
Obj* result;
int i;
if ( == nobjs)
{
return chunk;
}
int index = FREELIST_INDEX(n);
MyFreeList = FreeList[index];
result = (Obj *)chunk;
MyFreeList = (Obj *)(chunk + n);//取出剩下的节点挨个儿查到对应的自由链表位置上去
Obj* end = (Obj *)MyFreeList;
for (i = ;; i++)
{
if (nobjs - == i)
{
end->FreeListLink = ;
break;
}
else
{
end->FreeListLink = (Obj *)(chunk + (i + )*n);
}
}
return result;
}
static char *ChunkAlloc(size_t size, int &nobjs)
{
char *result;
size_t totalbytes = size*nobjs;
size_t bytesleft = EndFree - StartFree;
if (bytesleft >= totalbytes)//内存池的内存完全够用
{
result = StartFree;
StartFree += totalbytes;
return result;
}
else if (bytesleft >= size)//内存池的内存虽然不够20个,但是至少够1个
{
nobjs = bytesleft / size;
totalbytes = nobjs*size;
result = StartFree;
StartFree += totalbytes;
return result;
}
else
{
size_t bytestoget = * totalbytes + ROUND_UP(HeapSize >> );
if (bytesleft > )//还有一部分内存没有分配,需要先分配出去
{
int index = FREELIST_INDEX(bytesleft);
Obj * volatile MyFreeList = FreeList[index];
Obj *tmp = (Obj *)StartFree;
tmp->FreeListLink = MyFreeList;//头插
MyFreeList = tmp;
}
StartFree = (char *)malloc(bytestoget);
if ( == StartFree)
{
int i;
Obj *volatile MyFreeList, *p;
for (i = size; i <= __MAX_BYTES; i += __ALIGN) {
int index = FREELIST_INDEX(i);
MyFreeList = FreeList[index];
p = MyFreeList;
if ( != p)
{
MyFreeList = p->FreeListLink;
StartFree = (char *)p;
EndFree = StartFree + i;
return(ChunkAlloc(size, nobjs));
}
}
EndFree = ;
StartFree = (char *)MallocAlloc::Allocate(bytestoget); }
HeapSize += bytestoget;
EndFree = StartFree + bytestoget;
return (ChunkAlloc(size, nobjs));
}
} public:
static void *Allocate(size_t n)
{
Obj* volatile MyFreeList;
Obj* result;
if (n > (size_t)__MAX_BYTES)//大于128字节到一级配置器中去
{
return MallocAlloc::Allocate(n);
}
int index = FREELIST_INDEX(n);
MyFreeList = FreeList[index];
result = MyFreeList;
if (result == )
{
void *r = Refill(ROUND_UP(n));
return r;
}
MyFreeList = result->FreeListLink;
return result;
} static void Deallocate(void *p, size_t n)
{
int index = FREELIST_INDEX(n);
Obj* q = (Obj *)p;
Obj* volatile MyFreeList;
if (n > (size_t)__MAX_BYTES)
{
MallocAlloc::Deallocate(p, n);
return;
}
MyFreeList = FreeList[index];//把内存块还给自由链表,采用头插的方式插入自由链表
q->FreeListLink = MyFreeList;
MyFreeList = q; } };
template <bool threads, int inst>
typename __DefaultAllocTemplate<threads, inst>::Obj* volatile __DefaultAllocTemplate<threads, inst>::FreeList[__DefaultAllocTemplate<threads, inst>::__NFREELISTS]; template <bool threads, int inst>
char* __DefaultAllocTemplate<threads, inst>::StartFree = ;
template <bool threads, int inst>
char* __DefaultAllocTemplate<threads, inst>::EndFree = ;
template <bool threads, int inst>
size_t __DefaultAllocTemplate<threads, inst>::HeapSize = ;; typedef __DefaultAllocTemplate<, > Alloc; #endif void Test1()
{
// 测试调用一级配置器分配内存
cout << "测试调用一级配置器分配内存" << endl;
char*p1 = SimpleAlloc<char, Alloc>::Allocate();
SimpleAlloc<char, Alloc>::Deallocate(p1, ); // 测试调用二级配置器分配内存
cout << "测试调用二级配置器分配内存" << endl;
char*p2 = SimpleAlloc<char, Alloc>::Allocate();
char*p3 = SimpleAlloc<char, Alloc>::Allocate();
char*p4 = SimpleAlloc<char, Alloc>::Allocate();
char*p5 = SimpleAlloc<char, Alloc>::Allocate();
SimpleAlloc<char, Alloc>::Deallocate(p2, );
SimpleAlloc<char, Alloc>::Deallocate(p3, );
SimpleAlloc<char, Alloc>::Deallocate(p4, );
SimpleAlloc<char, Alloc>::Deallocate(p5, ); for (int i = ; i < ; ++i)
{
printf("测试第%d次分配\n", i + );
char*p = SimpleAlloc<char, Alloc>::Allocate();
}
}
STL_Iterator.h
#pragma once struct InputIterator_tag {};
struct OutputIterator_tag {};
struct ForwardIterator_tag : public InputIterator_tag {};
struct BidirectionalIterator_tag : public ForwardIterator_tag {};
struct RandomAccessIterator_tag : public BidirectionalIterator_tag {}; template <class T, class Distance> struct InputIterator {
typedef InputIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; struct OutputIterator {
typedef OutputIterator_tag IteratorCategory;
typedef void ValueType;
typedef void DifferenceType;
typedef void Pointer;
typedef void Reference;
}; template <class T, class Distance> struct ForwardIterator {
typedef ForwardIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template <class T, class Distance> struct BidirectionalIterator {
typedef BidirectionalIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template <class T, class Distance> struct RandomAccessIterator {
typedef RandomAccessIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template <class Category, class T, class Distance = size_t, class Pointer = T*, class Reference = T&>
struct Iterator {
typedef Category IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef Pointer Pointer;
typedef Reference Reference;
}; template <class Iterator>
struct IteratorTraits
{
typedef typename Iterator::IteratorCategory IteratorCategory;
typedef typename Iterator::ValueType ValueType;
typedef typename Iterator::DifferenceType DifferenceType;
typedef typename Iterator::Pointer Pointer;
typedef typename Iterator::Reference Reference;
};//ÀàÐÍÝÍÈ¡»ú template <class T>
struct IteratorTraits<T*>
{
typedef RandomAccessIterator_tag IteratorCategory;
typedef T ValueType;
typedef ptrdiff_t DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template<class InputIterator>
int Distance(InputIterator first, InputIterator last)
{
return _Distance(first, last, IteratorTraits<InputIterator>::IteratorCategory());
} template<class InputIterator>
int _Distance(InputIterator first, InputIterator last, ForwardIterator_tag)
{
int count = ;
while (first != last)
{
count++;
first++;
}
return count;
} template<class InputIterator>
int _Distance(InputIterator first, InputIterator last, RandomAccessIterator_tag)
{
return last - first;
} //template <class Iterator>
//inline typename IteratorTraits<Iterator>::DifferenceType*
//DifferenceType(const Iterator&) {
// return static_cast<typename IteratorTraits<Iterator>::DifferenceType*>(0);
//} template <class T, class Distance>
inline T* ValueType(const InputIterator<T, Distance>&) {
return (T*)();
} template <class T, class Distance>
inline T* ValueType(const ForwardIterator<T, Distance>&) {
return (T*)();
} template <class T, class Distance>
inline T* ValueType(const BidirectionalIterator<T, Distance>&) {
return (T*)();
} template <class T, class Distance>
inline T* ValueType(const RandomAccessIterator<T, Distance>&) {
return (T*)();
} template <class T>
inline T* ValueType(const T*) { return (T*)(); }
STL_TypeTraits.h
#pragma once struct InputIterator_tag {};
struct OutputIterator_tag {};
struct ForwardIterator_tag : public InputIterator_tag {};
struct BidirectionalIterator_tag : public ForwardIterator_tag {};
struct RandomAccessIterator_tag : public BidirectionalIterator_tag {}; template <class T, class Distance> struct InputIterator {
typedef InputIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; struct OutputIterator {
typedef OutputIterator_tag IteratorCategory;
typedef void ValueType;
typedef void DifferenceType;
typedef void Pointer;
typedef void Reference;
}; template <class T, class Distance> struct ForwardIterator {
typedef ForwardIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template <class T, class Distance> struct BidirectionalIterator {
typedef BidirectionalIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template <class T, class Distance> struct RandomAccessIterator {
typedef RandomAccessIterator_tag IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template <class Category, class T, class Distance = size_t, class Pointer = T*, class Reference = T&>
struct Iterator {
typedef Category IteratorCategory;
typedef T ValueType;
typedef Distance DifferenceType;
typedef Pointer Pointer;
typedef Reference Reference;
}; template <class Iterator>
struct IteratorTraits
{
typedef typename Iterator::IteratorCategory IteratorCategory;
typedef typename Iterator::ValueType ValueType;
typedef typename Iterator::DifferenceType DifferenceType;
typedef typename Iterator::Pointer Pointer;
typedef typename Iterator::Reference Reference;
};//ÀàÐÍÝÍÈ¡»ú template <class T>
struct IteratorTraits<T*>
{
typedef RandomAccessIterator_tag IteratorCategory;
typedef T ValueType;
typedef ptrdiff_t DifferenceType;
typedef T* Pointer;
typedef T& Reference;
}; template<class InputIterator>
int Distance(InputIterator first, InputIterator last)
{
return _Distance(first, last, IteratorTraits<InputIterator>::IteratorCategory());
} template<class InputIterator>
int _Distance(InputIterator first, InputIterator last, ForwardIterator_tag)
{
int count = ;
while (first != last)
{
count++;
first++;
}
return count;
} template<class InputIterator>
int _Distance(InputIterator first, InputIterator last, RandomAccessIterator_tag)
{
return last - first;
} //template <class Iterator>
//inline typename IteratorTraits<Iterator>::DifferenceType*
//DifferenceType(const Iterator&) {
// return static_cast<typename IteratorTraits<Iterator>::DifferenceType*>(0);
//} template <class T, class Distance>
inline T* ValueType(const InputIterator<T, Distance>&) {
return (T*)();
} template <class T, class Distance>
inline T* ValueType(const ForwardIterator<T, Distance>&) {
return (T*)();
} template <class T, class Distance>
inline T* ValueType(const BidirectionalIterator<T, Distance>&) {
return (T*)();
} template <class T, class Distance>
inline T* ValueType(const RandomAccessIterator<T, Distance>&) {
return (T*)();
} template <class T>
inline T* ValueType(const T*) { return (T*)(); }
类型萃取分为POD类型(基本数据类型)和非POD类型,POD类型有库提供的构造函数,析构函数,拷贝构造等,而非POD类型没有,需要用户自定义这些功能。使用类型萃取是把这两种类型分开,然后对POD类型不用处理对非POD类型自定义实现功能,从而达到代码重用。
参考:http://www.cnblogs.com/lenomirei/p/5379289.html STL的迭代器和类型萃取
http://blog.csdn.net/lf_2016/article/details/53511648 揭秘——STL空间配置器
模拟实现STL库的更多相关文章
- [转] C++的STL库,vector sort排序时间复杂度 及常见容器比较
http://www.169it.com/article/3215620760.html http://www.cnblogs.com/sharpfeng/archive/2012/09/18/269 ...
- 使用STL库sort函数对vector进行排序
使用STL库sort函数对vector进行排序,vector的内容为对象的指针,而不是对象. 代码如下 #include <stdio.h> #include <vector> ...
- 【实习记】2014-08-15文档太少看着源码用cgicc+stl库之模板谓词函数对象
总结1: 今天找到了昨天scanf的问题答案,scanf与printf一样的神奇而复杂,稍不留神,就会被坑.scanf函数在读入非空白符分割的多个字符串的解决方法是这个:/* 以 | 分割 * ...
- STL库list::sort()实现深度解析
原创,转载请注明出处:STL库list::sort()实现深度解析 list模板的定义以及一些基本成员函数的实现这里我就不赘述了,还不清楚的同学可以到网上查找相关资料或者直接查看侯捷翻译的<ST ...
- STL库中string类内存布局的探究
在STL中有着一个类就是string类,他的内存布局和存储机制究竟是怎么样的呢? 这就是建立好的string 可以看出,图中用黄色框框标注的部分就是主要区域 我们用来给string对象进行初始化的字符 ...
- 关于STL库中的max min swap
嗯... 不得不说c++中的STL库是一个神奇的东西 可以使你的代码显得更加简洁.... 今天就只讲STL中的三个鬼畜: max min swap 具体操作 ...
- 【uva 1152】4 Values Whose Sum is Zero(算法效率--中途相遇法+Hash或STL库)
题意:给定4个N元素几个A,B,C,D,要求分别从中选取一个元素a,b,c,d使得a+b+c+d=0.问有多少种选法.(N≤4000,D≤2^28) 解法:首先我们从最直接最暴力的方法开始思考:四重循 ...
- vscode无法运行和调试使用了部分stl库的程序(无法定位程序输入点__gxx_personality_v0的一个解决方法)
一.起因 vscode 不能运行带有部分 stl 库的程序,编译不会报错,运行也不会报错但是也没有结果,调试的话会有下图中报错,如果没有string或者vector一切正常. 二.分析 cmd 中运 ...
- c++中STL库简介及使用说明
作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的.STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现.本教程旨在传播和普及STL的基础知识,若能借此机 ...
随机推荐
- pycharm打开脚本报错Gtk-Message: Failed to load module "canberra-gtk-module"
解决方法 sudo apt-get install libcanberra-gtk-module
- C++11之nullptr
[C++11空指针] 1.NULL的问题 class Test { public: void TestWork(int index) { std::cout << "TestWo ...
- Android中Activity的四种启动方式
谈到Activity的启动方式必须要说的是数据结构中的栈.栈是一种只能从一端进入存储数据的线性表,它以先进后出的原则存储数据,先进入的数据压入栈底,后进入的数据在栈顶.需要读取数据的时候就需要从顶部开 ...
- 跨版本mysqldump恢复报错Errno1449
已经有一套主从mysql,新增两个slave主库Server version: 5.6.22-log MySQL Community Server (GPL)旧从库Server version: 5. ...
- (转)Docker镜像中的base镜像理解
base 镜像有两层含义: 不依赖其他镜像,从 scratch 构建. 其他镜像可以之为基础进行扩展. 所以,能称作 base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ub ...
- [C++] Lvalue and Rvalue Reference
Lvalue and Rvalue Reference int a = 10;// a is in stack int& ra = a; // 左值引用 int* && pa ...
- js运算浮点数
在js中做小数:9.3+0.3会发现,得到的结果并不是9.6,而是9.600000000000001.这是为什么? Javascript采用了IEEE-745浮点数表示法,这是一种二进制表示法,可以精 ...
- (转)unordered_map与map的对比(C++11新特性)
unordered_map和map类似,都是存储的key-value的值,可以通过key快速索引到value.不同的是unordered_map不会根据key的大小进行排序, 存储时是根据key的ha ...
- jQuary总结5:传递一个dom对象
1 传递一个dom对象 //html <div></div> <p id="p"></p> //js var p = documen ...
- 弱网测试弱网测试—Network-Emulator-Toolkit
原文:https://blog.csdn.net/no1mwb/article/details/53638681