操作系统:centos 6.4
STL源码版本:3.3

前言:
    要看一个项目的源码,首先要选中切入点。
    那么在sgi stl 标准库中,其切入点是什么呢?
    答案是:stl_config.h 文件。

不同的编译器对C++语言的支持程度不尽相同。为了具备广泛移植能力,SGI STL  定义了一个环境组态文件<stl_config.h>。
其中声明了许多宏定义,在预编译的时候,通过这些宏定义来编译出对于平台的程序。

1,stl_config.h在linux平台下的实现:
    
    1.1)为了知道linux平台下sgi stl 的宏定义有那些是被定义了的,有个简单,直接的方法,直接输出其宏名字。
        测试代码如下:

#include <iostream>
#include <stdio.h>
using namespace std; void test(void)
{
#ifdef _PTHREADS
cout<<"define __STL_PTHREADS"<<endl;
#endif # if defined(__sgi) && !defined(__GNUC__)
cout<<"__sgi begin"<<endl;
# if !defined(_BOOL)
cout<<"__STL_NEED_BOOL"<<endl;
# endif
# if !defined(_TYPENAME_IS_KEYWORD)
cout<<"__STL_NEED_TYPENAME"<<endl;
# endif
# ifdef _PARTIAL_SPECIALIZATION_OF_CLASS_TEMPLATES
cout<<"__STL_CLASS_PARTIAL_SPECIALIZATION"<<endl;
# endif
# ifdef _MEMBER_TEMPLATES
cout<<"__STL_MEMBER_TEMPLATES"<<endl;
# endif
# if !defined(_EXPLICIT_IS_KEYWORD)
cout<<"__STL_NEED_EXPLICIT"<<endl;
# endif
# ifdef __EXCEPTIONS
cout<<"__STL_USE_EXCEPTIONS"<<endl;
# endif
# if (_COMPILER_VERSION >= ) && defined(_NAMESPACES)
cout<<"__STL_USE_NAMESPACES"<<endl;
# endif
# if !defined(_NOTHREADS) && !defined(__STL_PTHREADS)
cout<<"__STL_SGI_THREADS"<<endl;
# endif
cout<<"__sgi end"<<endl<<endl;
# endif # ifdef __GNUC__
cout<<"__GNUC__ begin"<<endl;
# include <_G_config.h>
# if __GNUC__ < || (__GNUC__ == && __GNUC_MINOR__ < )
cout<<"__STL_STATIC_TEMPLATE_MEMBER_BUG"<<endl;
cout<<"__STL_NEED_TYPENAME"<<endl;
cout<<"__STL_NEED_EXPLICIT"<<endl;
# else
cout<<"__STL_CLASS_PARTIAL_SPECIALIZATION"<<endl;
cout<<"__STL_FUNCTION_TMPL_PARTIAL_ORDER"<<endl;
cout<<"__STL_EXPLICIT_FUNCTION_TMPL_ARGS"<<endl;
cout<<"__STL_MEMBER_TEMPLATES"<<endl;
# endif
/* glibc pre 2.0 is very buggy. We have to disable thread for it.
It should be upgraded to glibc 2.0 or later. */
# if !defined(_NOTHREADS) && __GLIBC__ >= && defined(_G_USING_THUNKS)
cout<<"__STL_PTHREADS"<<endl;
# endif
# ifdef __EXCEPTIONS
cout<<"__STL_USE_EXCEPTIONS"<<endl;
# endif
cout<<"__GNUC__ end"<<endl<<endl;
# endif # if defined(__SUNPRO_CC)
cout<<"__SUNPRO_CC begin"<<endl;
cout<<"__STL_NEED_BOOL"<<endl;
cout<<"__STL_NEED_TYPENAME"<<endl;
cout<<"__STL_NEED_EXPLICIT"<<endl;
cout<<"__STL_USE_EXCEPTIONS"<<endl;
cout<<"__SUNPRO_CC end"<<endl<<endl;
# endif # if defined(__COMO__)
cout<<"__COMO__ begin"<<endl;
cout<<"__STL_MEMBER_TEMPLATES"<<endl;
cout<<"__STL_CLASS_PARTIAL_SPECIALIZATION"<<endl;
cout<<"__STL_USE_EXCEPTIONS"<<endl;
cout<<"__STL_USE_NAMESPACES"<<endl;
cout<<"__COMO__ end"<<endl<<endl;
# endif # if defined(_MSC_VER)
cout<<"_MSC_VER begin"<<endl;
# if _MSC_VER >
cout<<"include <yvals.h>"<<endl;
# else
cout<<"__STL_NEED_BOOL"<<endl;
# endif
cout<<"__STL_NO_DRAND48"<<endl;
cout<<"__STL_NEED_TYPENAME"<<endl;
# if _MSC_VER <
cout<<"__STL_NEED_EXPLICIT"<<endl;
# endif
cout<<"__STL_NON_TYPE_TMPL_PARAM_BUG"<<endl;
cout<<"__SGI_STL_NO_ARROW_OPERATOR"<<endl;
# ifdef _CPPUNWIND
cout<<"__STL_USE_EXCEPTIONS"<<endl;
# endif
# ifdef _MT
cout<<"__STL_WIN32THREADS"<<endl;
# endif
cout<<"_MSC_VER end"<<endl<<endl;
# endif # if defined(__BORLANDC__)
cout<<"__BORLANDC__ begin"<<endl;
cout<<"__STL_NO_DRAND48"<<endl;
cout<<"__STL_NEED_TYPENAME"<<endl;
cout<<"__STL_LIMITED_DEFAULT_TEMPLATES"<<endl;
cout<<"__SGI_STL_NO_ARROW_OPERATOR"<<endl;
cout<<"__STL_NON_TYPE_TMPL_PARAM_BUG"<<endl;
# ifdef _CPPUNWIND
cout<<"__STL_USE_EXCEPTIONS"<<endl;
# endif
# ifdef __MT__
cout<<"__STL_WIN32THREADS"<<endl;
# endif
cout<<"__BORLANDC__ end"<<endl<<endl;
# endif # if defined(__STL_NEED_BOOL)
cout<<"__STL_NEED_BOOL begin"<<endl;
cout<<"typedef int bool;"<<endl;
cout<<"define true 1"<<endl;
cout<<"define false 0"<<endl;
cout<<"__STL_NEED_BOOL end"<<endl<<endl;
# endif # ifdef __STL_NEED_TYPENAME
cout<<"define typename"<<endl;
# endif # ifdef __STL_NEED_EXPLICIT
cout<<"define explicit"<<endl;
# endif # ifdef __STL_EXPLICIT_FUNCTION_TMPL_ARGS
cout<<"__STL_NULL_TMPL_ARGS <>"<<endl;
# else
cout<<"__STL_NULL_TMPL_ARGS"<<endl;
# endif # ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
cout<<"__STL_TEMPLATE_NULL template<>"<<endl;
# else
cout<<"__STL_TEMPLATE_NULL"<<endl;
# endif // __STL_NO_NAMESPACES is a hook so that users can disable namespaces
// without having to edit library headers.
# if defined(__STL_USE_NAMESPACES) && !defined(__STL_NO_NAMESPACES)
cout<<"__STL_USE_NAMESPACES begin"<<endl;
cout<<"__STD std"<<endl;
cout<<"__STL_BEGIN_NAMESPACE namespace std {"<<endl;
cout<<"__STL_END_NAMESPACE }"<<endl;
cout<<"__STL_USE_NAMESPACE_FOR_RELOPS"<<endl;
cout<<"__STL_BEGIN_RELOPS_NAMESPACE namespace std {"<<endl;
cout<<"__STL_END_RELOPS_NAMESPACE }"<<endl;
cout<<"__STD_RELOPS std"<<endl;
cout<<"__STL_USE_NAMESPACES end"<<endl<<endl;
# else
cout<<"! __STL_USE_NAMESPACES begin"<<endl;
cout<<"__STD "<<endl;
cout<<"__STL_BEGIN_NAMESPACE "<<endl;
cout<<"__STL_END_NAMESPACE "<<endl;
cout<<"__STL_USE_NAMESPACE_FOR_RELOPS"<<endl;
cout<<"__STL_BEGIN_RELOPS_NAMESPACE "<<endl;
cout<<"__STL_END_RELOPS_NAMESPACE "<<endl;
cout<<"__STD_RELOPS "<<endl;
cout<<"! __STL_USE_NAMESPACES end"<<endl<<endl;
# endif # ifdef __STL_USE_EXCEPTIONS
cout<<"__STL_USE_EXCEPTIONS begin"<<endl;
cout<<"__STL_TRY try"<<endl;
cout<<"__STL_CATCH_ALL catch(...)"<<endl;
cout<<"__STL_RETHROW throw"<<endl;
cout<<"__STL_NOTHROW throw()"<<endl;
cout<<"__STL_UNWIND(action) catch(...) { action; throw; }"<<endl;
cout<<"__STL_USE_EXCEPTIONS end"<<endl<<endl;
# else
cout<<"! __STL_USE_EXCEPTIONS begin"<<endl;
cout<<"__STL_TRY "<<endl;
cout<<"__STL_CATCH_ALL if (false)"<<endl;
cout<<"__STL_RETHROW "<<endl;
cout<<"__STL_NOTHROW "<<endl;
cout<<"__STL_UNWIND(action) "<<endl;
cout<<"! __STL_USE_EXCEPTIONS end"<<endl<<endl;
# endif #ifdef __STL_ASSERTIONS
# include <stdio.h>
cout<<"__stl_assert(expr) \
if (!(expr)) { fprintf(stderr, \"%s:%d STL assertion failure: %s\n\", \
__FILE__, __LINE__, # expr); abort(); }"<<endl;
#else
cout<<"__stl_assert(expr)"<<endl;
#endif } int main(void)
{
test(); return ;
}

运行结果:

[root@localhost stlsource]# g++ -o lconfig1 lconfig1.cpp
[root@localhost stlsource]# ./lconfig1
__GNUC__ begin
__STL_CLASS_PARTIAL_SPECIALIZATION
__STL_FUNCTION_TMPL_PARTIAL_ORDER
__STL_EXPLICIT_FUNCTION_TMPL_ARGS
__STL_MEMBER_TEMPLATES
__STL_PTHREADS
__STL_USE_EXCEPTIONS
__GNUC__ end __STL_NULL_TMPL_ARGS
__STL_TEMPLATE_NULL
! __STL_USE_NAMESPACES begin
__STD
__STL_BEGIN_NAMESPACE
__STL_END_NAMESPACE
__STL_USE_NAMESPACE_FOR_RELOPS
__STL_BEGIN_RELOPS_NAMESPACE
__STL_END_RELOPS_NAMESPACE
__STD_RELOPS
! __STL_USE_NAMESPACES end ! __STL_USE_EXCEPTIONS begin
__STL_TRY
__STL_CATCH_ALL if (false)
__STL_RETHROW
__STL_NOTHROW
__STL_UNWIND(action)
! __STL_USE_EXCEPTIONS end __stl_assert(expr)

1.2)通过以上的测试,可以得到在linux平台下,stl_config.h 的实现定义如下:
        为了缩小篇幅,把相关的版权信息的屏蔽了。

#ifndef __STL_CONFIG_H
# define __STL_CONFIG_H # ifdef __GNUC__
# include <_G_config.h>
# define __STL_CLASS_PARTIAL_SPECIALIZATION
# define __STL_FUNCTION_TMPL_PARTIAL_ORDER
# define __STL_EXPLICIT_FUNCTION_TMPL_ARGS
# define __STL_MEMBER_TEMPLATES
# define __STL_PTHREADS
# define __STL_USE_EXCEPTIONS
# endif # define __STL_NULL_TMPL_ARGS
# define __STL_TEMPLATE_NULL # define __STD
# define __STL_BEGIN_NAMESPACE
# define __STL_END_NAMESPACE
# undef __STL_USE_NAMESPACE_FOR_RELOPS
# define __STL_BEGIN_RELOPS_NAMESPACE
# define __STL_END_RELOPS_NAMESPACE
# define __STD_RELOPS # define __STL_TRY
# define __STL_CATCH_ALL if (false)
# define __STL_RETHROW
# define __STL_NOTHROW
# define __STL_UNWIND(action) # define __stl_assert(expr) #endif /* __STL_CONFIG_H */ // Local Variables:
// mode:C++
// End:

2,对stl_config.h中的宏的详解
    2.1)__STL_STATIC_TEMPLATE_MEMBER_BUG

    1. 如果编译器不支持static members of template classes(模板类静态成员),
    2. //       则定义__STL_STATIC_TEMPLATE_MEMBER_BUG
#include<iostream>
using namespace std; template <typename T>
class testClass {
public:
static int _data;
};
//只对成员实现特化,记得加上template<>
template<>
int testClass<int>::_data=; template<>
int testClass<char>::_data=; int main()
{
cout<<testClass<int>::_data<<endl;
cout<<testClass<char>::_data<<endl; testClass<int> Obji1,Obji2;
testClass<char> Objc1,Objc2; cout<<Obji1._data<<endl;
cout<<Obji2._data<<endl;
cout<<Objc1._data<<endl;
cout<<Objc2._data<<endl; Obji1._data=;
Objc1._data=; cout<<Obji1._data<<endl;
cout<<Obji2._data<<endl;
cout<<Objc1._data<<endl;
cout<<Objc2._data<<endl;
}

运行结果:

[root@localhost stlsource]# ./lconfig3 

2.2)__STL_CLASS_PARTIAL_SPECIALIZATION

    1. 如果编译器支持partial specialization of class templates(局部特殊化的类模板),
    2. //       则定义__STL_CLASS_PARTIAL_SPECIALIZATION
    3. //       参考文献: http://msdn.microsoft.com/en-us/library/9w7t3kf1(v=VS.71).aspx
#include<iostream>
using namespace std; template <class I,class O>
struct testClass
{
testClass() {cout<<"I,O"<<endl;}
};
//对类实现偏特化
template <class T>
struct testClass<T*,T*>
{
testClass() {cout<<"T*,T*"<<endl;}
};
//对类实现偏特化
template<class T>
struct testClass<const T*,T*>
{
testClass(){ cout<<"const T*,T*"<<endl;}
}; int main()
{
testClass<int,char> obj1;
testClass<int*,int*> obj2;
testClass<const int*,int*> obj3;
}

运行结果:

[root@localhost stlsource]# ./lconfig5
I,O
T*,T*
const T*,T*

2.3)__STL_FUNCTION_TMPL_PARTIAL_ORDER

    1. 如果编译器支持partial ordering of function templates(部分排序函数模板),
    2. //       则定义__STL_FUNCTION_TMPL_PARTIAL_ORDER
    3. //       参考资料: http://msdn.microsoft.com/zh-cn/library/zaycz069.aspx
#include<iostream>
using namespace std; class alloc{
}; template <class T,class Alloc=alloc>
class vector{
public:
void swap(vector<T,Alloc>&) {cout<<"swap()"<<endl;}
};
//本来是#ifdef__STL_FUNCION_TMPL_PARTIAL_ORDER,但是貌似不支持
#ifndef __STL_FUNCION_TMPL_PARTIAL_ORDER
template <class T,class Alloc>
inline void swap(vector<T,Alloc>& x,vector<T,Alloc>& y)
{
x.swap(y);
}
#endif // __STL_FUNCION_TMPL_PARTIAL_ORDER int main()
{
vector<int>x,y;
swap(x,y);
}

运行结果:

[root@localhost stlsource]# ./lconfig6
swap()

2.4)__STL_EXPLICIT_FUNCTION_TMPL_ARGS 
        整个 SGI STL  内都没有用到此一常数定义

    1. 如果编译器支持calling a function template by providing its template
    2. //       arguments explicitly(显式指定调用模板函数的模板参数)

2.5)__STL_MEMBER_TEMPLATES 

  1. 如果编译器支持template members of classes(类模板成员),
  2. //       则定义__STL_MEMBER_TEMPLATES
#include<iostream>
#include<typeinfo>
using namespace std; class alloc{
};
//类模板
template <typename T,typename Alloc=alloc>
class vector{
public:
typedef T value_type;
typedef value_type* iterator;
//函数模板
template <typename I>
void insert(iterator position,I first,I last)
{
cout<<"insert()"<<endl;
cout<<typeid(I).name()<<endl;
}
}; int main()
{
int ia[]={,,,,};
vector<int> x;
vector<int>::iterator ite;
x.insert(ite,*ia,*(ia+));
}

运行结果:

[root@localhost stlsource]# ./lconfig8
insert()
i

2.6)__STL_LIMITED_DEFAULT_TEMPLATES

    1. 如果编译器不能根据前一个模板参数设定后面的默认模板参数,
    2. //       则定义__STL_LIMITED_DEFAULT_TEMPLATES
#include<iostream>
#include<cstddef>
using namespace std; class alloc{}; template <typename T,class Alloc=alloc,size_t Bufsiz=0>
class deque{
public:
deque(){cout<<"deque"<<endl;}
}; template <typename T,class Sequence=deque<T> >
class stack{
public:
stack(){ cout<<"stack"<<endl;}
private:
Sequence c;//调用deque的构造函数初始化
}; int main()
{
stack<int> x;
}

  运行结果:

[root@localhost stlsource]# ./lconfig10
deque
stack

      2.7)__STL_NON_TYPE_TMPL_PARAM_BUG 

    1. 如果编译器处理模板函数的non-type模板参数类型推断有困难,
    2. //       则定义__STL_NON_TYPE_TMPL_PARAM_BUG
#include<iostream>
#include<cstddef>
using namespace std; class alloc{}; inline size_t __deque_buf_size(size_t n,size_t sz)
{
return n!=0?n:(sz<512?size_t(512/sz):size_t(1));
} template <class T,class Ref,class Ptr,size_t Bufsiz>
struct __deque_iterator{
typedef __deque_iterator<T,T&,T*,Bufsiz> iterator;
typedef __deque_iterator<T,const T&,const T*,Bufsiz> const_iterator;
static size_t buffer_size() {return __deque_buf_size(Bufsiz,sizeof(T));}
}; template <class T,class Alloc=alloc,size_t Bufsiz=0>
class deque
{
public:
typedef __deque_iterator<T,T&,T*,Bufsiz> iterator;
}; int main()
{
cout<<deque<int>::iterator::buffer_size()<<endl;
cout<<deque<int,alloc,64>::iterator::buffer_size()<<endl;
}

  运行结果:

  

     2.8)__STL_NULL_TMPL_ARGS(bound friend template friend)

<stl_config.h>定义__STL_NULL_TMPL_ARGS如下:

#ifdef __STL_NULL_TMPL_ARGS
# define __STL_NULL_TMPL_ARGS <>
#else
# define __STL_NULL_TMPL_ARGS
#endif

  这个组态常量常常出现在类似这样的场合(class template的friend函数声明)。

// in <stl_stack.h>
template<class T,class Sequence=deque<T> >
class stack{
friend bool operator==___STL_NULL_TMPL_ARGS(const stack &,const stack&);
friend bool operator< __STL_NULL_TMPL_ARGS(const stack&,const stack&);
...
}; 展开后就变成了: template<class T,class Sequence=deque<T> >
class stack{
friend bool operator== <>(const stack &,const stack&);
friend bool operator< <>(const stack&,const stack&);
...
};

  这种奇特的语法是为了实现所谓的 bound friend templates,也就是说class template的某个具现体(instantiation)与其friend function template的某个具现体有一对一的关系。下面是测试程序:

#include<iostream>
#include<cstddef>
using namespace std; class alloc{}; template<class T,class Alloc=alloc,size_t BufSiz=0>
class deque
{
public:
deque(){cout<<"deque"<<endl;}
};
//类模板与友元的一对一关系需要前置声明
template<class T,class Sequence>
class stack; template<class T,class Sequence>
bool operator==(const stack<T,Sequence>& x,const stack<T,Sequence>& y); template<class T,class Sequence>
bool operator<(const stack<T,Sequence>& x,const stack<T,Sequence>& y); template<class T,class Sequence=deque<T> >
class stack
{
//friend bool operator==<T>(const stack<T>&,const stack<T>&);
//friend bool operator< <T>(const stack<T>&,const stack<T>&);
//下面的都是等价于上面的
//friend bool operator== <T>(const stack&,const stack&);
//friend bool operator< <T>(const stack&,const stack&); friend bool operator== <>(const stack&,const stack&);
friend bool operator< <>(const stack&,const stack&);
public:
stack(){cout<<"stack"<<endl;}
private:
Sequence c;
}; template<class T,class Sequence>
bool operator==(const stack<T,Sequence> &x,const stack<T,Sequence> &y)
{
return cout<<"operator=="<<'\t';
} template<class T,class Sequence>
bool operator<(const stack<T,Sequence> &x,const stack<T,Sequence> &y)
{
return cout<<"operator<"<<'\t';
} int main()
{
stack<int> x;
stack<int> y;
cout<<(x==y)<<endl;
cout<<(x<y)<<endl; stack<char> y1;
// cout<<(x==y1)<<endl;
// cout<<(x<y1)<<endl;
}

  运行结果:

2.9)__STL_TEMPLATE_NULL(class template explicit specialization)


<stl_config.h>定义了一个__STL_TEMPLATE_NULL如下:

#ifdef __STL_CLASS_PAPTIAL_SPECIALIZATION
#define __STL_TEMPLATE_NULL template<>
#else
#define __STL_TEMPLATE_NULL
#endif

  这个组态常量常常出现在类似这样的场合:

//in <type_traits.h>
template <class type> struct _type_traits {...};
__STL_TEMPLATE_NULL struct _type_traits<char> {}; //in <stl_hash_fun.h>
template <class key> struct hash{};
__STL_TEMPLATE_NULL struct hash<char> {};
__STL_TEMPLATE_NULL struct hash<unsigned char> {};

  展开后:

//in <type_traits.h>
template <class type> struct _type_traits {...};
template<> struct _type_traits<char> {}; //in <stl_hash_fun.h>
template <class key> struct hash{};
template<> struct hash<char> {};
template<> struct hash<unsigned char> {};

  这就是所谓的class template explicit specialization。

下面是一个测试程序:

#include<iostream>
//不能使用 using namespace std 这会将标准库中的hash引入,然后通不过
using std::cout;
using std::endl; //貌似我使用g++编译,定义为空不能通过
//#define __STL_TEMPLATE_NULL
#define __STL_TEMPLATE_NULL template<> template <class key>
struct hash
{
//重载函数调用运算符
void operator()()
{
cout<<"hash<T>"<<endl;
}
}; template<>
struct hash<char>
{
void operator()()
{
cout<<"hash<char>"<<endl;
}
}; __STL_TEMPLATE_NULL
struct hash<unsigned char>
{
void operator()()
{
cout<<"hash<unsigned char"<<endl;
}
}; int main()
{
hash<long> t1;
hash<char> t2;
hash<unsigned char> t3; t1();//函数对象和函数指针类似,可以作为可调用对象
t2();
t3();
}

  运行结果:

STL源码剖析—stl_config的更多相关文章

  1. STL"源码"剖析-重点知识总结

    STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略多 :) 1.STL概述 STL提供六大组件,彼此可以组合 ...

  2. 【转载】STL"源码"剖析-重点知识总结

    原文:STL"源码"剖析-重点知识总结 STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点 ...

  3. (原创滴~)STL源码剖析读书总结1——GP和内存管理

    读完侯捷先生的<STL源码剖析>,感觉真如他本人所说的"庖丁解牛,恢恢乎游刃有余",STL底层的实现一览无余,给人一种自己的C++水平又提升了一个level的幻觉,呵呵 ...

  4. 《STL源码剖析》环境配置

    首先,去侯捷网站下载相关文档:http://jjhou.boolan.com/jjwbooks-tass.htm. 这本书采用的是Cygnus C++ 2.91 for windows.下载地址:ht ...

  5. STL源码剖析读书笔记之vector

    STL源码剖析读书笔记之vector 1.vector概述 vector是一种序列式容器,我的理解是vector就像数组.但是数组有一个很大的问题就是当我们分配 一个一定大小的数组的时候,起初也许我们 ...

  6. STL源码剖析 迭代器(iterator)概念与编程技法(三)

    1 STL迭代器原理 1.1  迭代器(iterator)是一中检查容器内元素并遍历元素的数据类型,STL设计的精髓在于,把容器(Containers)和算法(Algorithms)分开,而迭代器(i ...

  7. STL"源码"剖析

    STL"源码"剖析-重点知识总结   STL是C++重要的组件之一,大学时看过<STL源码剖析>这本书,这几天复习了一下,总结出以下LZ认为比较重要的知识点,内容有点略 ...

  8. 《STL源码剖析》相关面试题总结

    原文链接:http://www.cnblogs.com/raichen/p/5817158.html 一.STL简介 STL提供六大组件,彼此可以组合套用: 容器容器就是各种数据结构,我就不多说,看看 ...

  9. STL源码剖析之序列式容器

    最近由于找工作需要,准备深入学习一下STL源码,我看的是侯捷所著的<STL源码剖析>.之所以看这本书主要是由于我过去曾经接触过一些台湾人,我一直觉得台湾人非常不错(这里不涉及任何政治,仅限 ...

随机推荐

  1. WARN [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED

    问题描述:hive 关于告警问题的解决:WARN  [main] conf.HiveConf (HiveConf.java:initialize(1488)) - DEPRECATED: Config ...

  2. ng的数据绑定

    ng创建了一个自己的事件循环,当浏览器事件(常用的dom事件,xhr事件等)发生时,对DOM对应的数据进行检查,若更改了,则标记为脏值,并进入更新循环,修改对应的(可能是多个) DOM的参数.这样就实 ...

  3. 一些CMS网站系统漏洞,练手用(持续更新)

    仅供拿shell,提权测试用,请勿恶意破坏 XuSoft系统: 后台万能密码:'or'='or'  可直接登陆,后台地址 /manage/login.asp inurl:ReadArticlemb.a ...

  4. 使用c语言编写cgi程序

    http://blog.chinaunix.net/uid-22566367-id-3109877.html 简单的说,cgi是沟通HTML表单和服务器端程序的接口,是可以被其他语言所应用的一个规范集 ...

  5. 解决方案-Microsoft Visual Studio 2012 已停止工作

    问题: 根本解决方案: 用管理员模式运行. 找到软件的安装目录 \Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe 然后如何保存管理员权限运行呢? ...

  6. 【译】iOS人性化界面指南(iOS Human Interface Guidelines)(一)

    1. 引言1.1 译者自述 我是一个表达能力一般的开发员,不管是书面表达,还是语言表达.在很早以前其实就有通过写博客锻炼这方面能力的想法,但水平有限实在没有什么拿得出手的东西分享.自2015年7月以来 ...

  7. [BZOJ 1048] [HAOI2007] 分割矩阵 【记忆化搜索】

    题目链接:BZOJ - 1048 题目分析 感觉这种分割矩阵之类的题目很多都是这样子的. 方差中用到的平均数是可以直接算出来的,然后记忆化搜索 Solve(x, xx, y, yy, k) 表示横坐标 ...

  8. Groovy学起来,这要和GRAILS,RUNDECK打成一片

    还好,以前看过RUBY和JAVA,GROOVY感觉和它们有点相似.. 并且,我觉得这个GROOVY比SCALA要简单些(函数式编程+OBJ) 作类比,毕竟是最快的学习方法. XXX,还有必修课和证券从 ...

  9. Rundeck,RUN起来!!

    零晨一点, 还好,跑起来了.. 满满的英文文档,肿么办?? 拿下!

  10. 揪出“凶手”——实战WinDbg分析电脑蓝屏原因

    http://www.appinn.com/blue-screen-search-code/ 蓝屏代码查询器 – 找出蓝屏的元凶 11 文章标签: windows / 系统 / 蓝屏. 蓝屏代码查询器 ...