求STL(C++)模板库的set.h头文件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求STL(C++)模板库的set.h头文件相关的知识,希望对你有一定的参考价值。

参考技术A /*
这就是头文件 你把下面的东西复制到一个记事本中保存为 SET
无后缀名
放在 c++\VC98\Include 路径下
*/

// set standard header

#if _MSC_VER > 1000
#pragma once
#endif

#ifndef _SET_
#define _SET_
#include <functional>
#include <xtree>

#ifdef _MSC_VER
#pragma pack(push,8)
#endif /* _MSC_VER */

_STD_BEGIN
// TEMPLATE CLASS set
template<class _K, class _Pr = less<_K>,
class _A = allocator<_K> >
class set
public:
typedef set<_K, _Pr, _A> _Myt;
typedef _K value_type;
struct _Kfn : public unary_function<value_type, _K>
const _K& operator()(const value_type& _X) const
return (_X);
;
typedef _Pr value_compare;
typedef _K key_type;
typedef _Pr key_compare;
typedef _A allocator_type;
typedef _Tree<_K, value_type, _Kfn, _Pr, _A> _Imp;
typedef _Imp::size_type size_type;
typedef _Imp::difference_type difference_type;
typedef _Imp::reference reference;
typedef _Imp::const_reference const_reference;
typedef _Imp::iterator iterator;
typedef _Imp::const_iterator const_iterator;
typedef _Imp::reverse_iterator reverse_iterator;
typedef _Imp::const_reverse_iterator const_reverse_iterator;
typedef pair<iterator, bool> _Pairib;
typedef pair<iterator, iterator> _Pairii;
typedef pair<const_iterator, const_iterator> _Paircc;
explicit set(const _Pr& _Pred = _Pr(), const _A& _Al = _A())
: _Tr(_Pred, false, _Al)
typedef const value_type *_It;
set(_It _F, _It _L, const _Pr& _Pred = _Pr(),
const _A& _Al = _A())
: _Tr(_Pred, false, _Al)
for (; _F != _L; ++_F)
_Tr.insert(*_F);
_Myt& operator=(const _Myt& _X)
_Tr = _X._Tr;
return (*this);
iterator begin()
return (_Tr.begin());
const_iterator begin() const
return (_Tr.begin());
iterator end()
return (_Tr.end());
const_iterator end() const
return (_Tr.end());
reverse_iterator rbegin()
return (_Tr.rbegin());
const_reverse_iterator rbegin() const
return (_Tr.rbegin());
reverse_iterator rend()
return (_Tr.rend());
const_reverse_iterator rend() const
return (_Tr.rend());
size_type size() const
return (_Tr.size());
size_type max_size() const
return (_Tr.max_size());
bool empty() const
return (_Tr.empty());
_A get_allocator() const
return (_Tr.get_allocator());
_Pairib insert(const value_type& _X)
_Imp::_Pairib _Ans = _Tr.insert(_X);
return (_Pairib(_Ans.first, _Ans.second));
iterator insert(iterator _P, const value_type& _X)
return (_Tr.insert((_Imp::iterator&)_P, _X));
void insert(_It _F, _It _L)
for (; _F != _L; ++_F)
_Tr.insert(*_F);
iterator erase(iterator _P)
return (_Tr.erase((_Imp::iterator&)_P));
iterator erase(iterator _F, iterator _L)
return (_Tr.erase((_Imp::iterator&)_F,
(_Imp::iterator&)_L));
size_type erase(const _K& _Kv)
return (_Tr.erase(_Kv));
void clear()
_Tr.clear();
void swap(_Myt& _X)
std::swap(_Tr, _X._Tr);
friend void swap(_Myt& _X, _Myt& _Y)
_X.swap(_Y);
key_compare key_comp() const
return (_Tr.key_comp());
value_compare value_comp() const
return (_Tr.key_comp());
const_iterator find(const _K& _Kv) const
return (_Tr.find(_Kv));
iterator find(const _K& _Kv)
return (_Tr.find(_Kv));
size_type count(const _K& _Kv) const
return (_Tr.count(_Kv));
iterator lower_bound(const _K& _Kv)
return (_Tr.lower_bound(_Kv));
const_iterator lower_bound(const _K& _Kv) const
return (_Tr.lower_bound(_Kv));
iterator upper_bound(const _K& _Kv)
return (_Tr.upper_bound(_Kv));
const_iterator upper_bound(const _K& _Kv) const
return (_Tr.upper_bound(_Kv));
_Pairii equal_range(const _K& _Kv)
return (_Tr.equal_range(_Kv));
_Paircc equal_range(const _K& _Kv) const
return (_Tr.equal_range(_Kv));
protected:
_Imp _Tr;
;
// set TEMPLATE OPERATORS
template<class _K, class _Pr, class _A> inline
bool operator==(const set<_K, _Pr, _A>& _X,
const set<_K, _Pr, _A>& _Y)
return (_X.size() == _Y.size()
&& equal(_X.begin(), _X.end(), _Y.begin()));
template<class _K, class _Pr, class _A> inline
bool operator!=(const set<_K, _Pr, _A>& _X,
const set<_K, _Pr, _A>& _Y)
return (!(_X == _Y));
template<class _K, class _Pr, class _A> inline
bool operator<(const set<_K, _Pr, _A>& _X,
const set<_K, _Pr, _A>& _Y)
return (lexicographical_compare(_X.begin(), _X.end(),
_Y.begin(), _Y.end()));
template<class _K, class _Pr, class _A> inline
bool operator>(const set<_K, _Pr, _A>& _X,
const set<_K, _Pr, _A>& _Y)
return (_Y < _X);
template<class _K, class _Pr, class _A> inline
bool operator<=(const set<_K, _Pr, _A>& _X,
const set<_K, _Pr, _A>& _Y)
return (!(_Y < _X));
template<class _K, class _Pr, class _A> inline
bool operator>=(const set<_K, _Pr, _A>& _X,
const set<_K, _Pr, _A>& _Y)
return (!(_X < _Y));
// TEMPLATE CLASS multiset
template<class _K, class _Pr = less<_K>,
class _A = allocator<_K> >
class multiset
public:
typedef multiset<_K, _Pr, _A> _Myt;
typedef _K value_type;
struct _Kfn : public unary_function<value_type, _K>
const _K& operator()(const value_type& _X) const
return (_X);
;
typedef _Pr value_compare;
typedef _K key_type;
typedef _Pr key_compare;
typedef _A allocator_type;
typedef _Tree<_K, value_type, _Kfn, _Pr, _A> _Imp;
typedef _Imp::size_type size_type;
typedef _Imp::difference_type difference_type;
typedef _Imp::reference reference;
typedef _Imp::const_reference const_reference;
typedef _Imp::iterator iterator;
typedef _Imp::const_iterator const_iterator;
typedef _Imp::reverse_iterator reverse_iterator;
typedef _Imp::const_reverse_iterator const_reverse_iterator;
typedef pair<iterator, iterator> _Pairii;
typedef pair<const_iterator, const_iterator> _Paircc;
explicit multiset(const _Pr& _Pred = _Pr(),
const _A& _Al = _A())
: _Tr(_Pred, true, _Al)
typedef const value_type *_It;
multiset(_It _F, _It _L, const _Pr& _Pred = _Pr(),
const _A& _Al = _A())
: _Tr(_Pred, true, _Al)
for (; _F != _L; ++_F)
_Tr.insert(*_F);
_Myt& operator=(const _Myt& _X)
_Tr = _X._Tr;
return (*this);
iterator begin()
return (_Tr.begin());
const_iterator begin() const
return (_Tr.begin());
iterator end()
return (_Tr.end());
const_iterator end() const
return (_Tr.end());
reverse_iterator rbegin()
return (_Tr.rbegin());
const_reverse_iterator rbegin() const
return (_Tr.rbegin());
reverse_iterator rend()
return (_Tr.rend());
const_reverse_iterator rend() const
return (_Tr.rend());
size_type size() const
return (_Tr.size());
size_type max_size() const
return (_Tr.max_size());
bool empty() const
return (_Tr.empty());
_A get_allocator() const
return (_Tr.get_allocator());
iterator insert(const value_type& _X)
return (_Tr.insert(_X).first);
iterator insert(iterator _P, const value_type& _X)
return (_Tr.insert((_Imp::iterator&)_P, _X));
void insert(_It _F, _It _L)
for (; _F != _L; ++_F)
_Tr.insert(*_F);
iterator erase(iterator _P)
return (_Tr.erase((_Imp::iterator&)_P));
iterator erase(iterator _F, iterator _L)
return (_Tr.erase((_Imp::iterator&)_F,
(_Imp::iterator&)_L));
size_type erase(const _K& _Kv)
return (_Tr.erase(_Kv));
void clear()
_Tr.clear();
void swap(_Myt& _X)
std::swap(_Tr, _X._Tr);
friend void swap(_Myt& _X, _Myt& _Y)
_X.swap(_Y);
key_compare key_comp() const
return (_Tr.key_comp());
value_compare value_comp() const
return (_Tr.key_comp());
iterator find(const _K& _Kv)
return (_Tr.find(_Kv));
const_iterator find(const _K& _Kv) const
return (_Tr.find(_Kv));
size_type count(const _K& _Kv) const
return (_Tr.count(_Kv));
iterator lower_bound(const _K& _Kv)
return (_Tr.lower_bound(_Kv));
const_iterator lower_bound(const _K& _Kv) const
return (_Tr.lower_bound(_Kv));
iterator upper_bound(const _K& _Kv)
return (_Tr.upper_bound(_Kv));
const_iterator upper_bound(const _K& _Kv) const
return (_Tr.upper_bound(_Kv));
_Pairii equal_range(const _K& _Kv)
return (_Tr.equal_range(_Kv));
_Paircc equal_range(const _K& _Kv) const
return (_Tr.equal_range(_Kv));
protected:
_Imp _Tr;
;
// multiset TEMPLATE OPERATORS
template<class _K, class _Pr, class _A> inline
bool operator==(const multiset<_K, _Pr, _A>& _X,
const multiset<_K, _Pr, _A>& _Y)
return (_X.size() == _Y.size()
&& equal(_X.begin(), _X.end(), _Y.begin()));
template<class _K, class _Pr, class _A> inline
bool operator!=(const multiset<_K, _Pr, _A>& _X,
const multiset<_K, _Pr, _A>& _Y)
return (!(_X == _Y));
template<class _K, class _Pr, class _A> inline
bool operator<(const multiset<_K, _Pr, _A>& _X,
const multiset<_K, _Pr, _A>& _Y)
return (lexicographical_compare(_X.begin(), _X.end(),
_Y.begin(), _Y.end()));
template<class _K, class _Pr, class _A> inline
bool operator>(const multiset<_K, _Pr, _A>& _X,
const multiset<_K, _Pr, _A>& _Y)
return (_Y < _X);
template<class _K, class _Pr, class _A> inline
bool operator<=(const multiset<_K, _Pr, _A>& _X,
const multiset<_K, _Pr, _A>& _Y)
return (!(_Y < _X));
template<class _K, class _Pr, class _A> inline
bool operator>=(const multiset<_K, _Pr, _A>& _X,
const multiset<_K, _Pr, _A>& _Y)
return (!(_X < _Y));
_STD_END
#ifdef _MSC_VER
#pragma pack(pop)
#endif /* _MSC_VER */

#endif /* _SET_ */

/*
* Copyright (c) 1995 by P.J. Plauger. ALL RIGHTS RESERVED.
* Consult your license regarding permissions and restrictions.
*/

/*
* This file is derived from software bearing the following
* restrictions:
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this
* software and its documentation for any purpose is hereby
* granted without fee, provided that the above copyright notice
* appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation.
* Hewlett-Packard Company makes no representations about the
* suitability of this software for any purpose. It is provided
* "as is" without express or implied warranty.
*/本回答被提问者采纳
参考技术B

所在路径:$(VCInstallDir)include

Header Only Library的介绍

Header Only Library把一个库的内容完全写在头文件中,不带任何cpp文件. 这是一个巧合,决不是C++的原始设计.

第一次这么做估计是STL.在80年代末C++编译器还不支持模块分离(现在也不支持,以后估计也不会支持了), STL的作者不得不把模板的实现写在头文件中, 使得一个STL库的实现绝大部分都展示给了使用者.

第一次广泛被接受估计还是在Boost库,它不只提出使用hpp做为Header Only Library的文件后缀(因为这些头文件再也不能用于C语言了),还把一些原本不是Header Only的库变成了Header Only.

抛开一些外部约束不谈,Header Only Library有自己的优点:Header Only Library - Wikipedia benefits of header only libraries - stackoverflow

1.轻量级编译流程,集成编译非常简单,只需要指明所在路径,在C++实现文件中包含所需头文件即可.
2.编译器优化可以做得更好.因为内联函数和所有的实现都在编译时可见,所以可以进行相当多的优化,包括一些全局优化.
3.更好的代码设计.因为不能使用写全局变量和静态变量,以及所有的代码都公开可见,使得很多不良设计都无处藏身.
4.减少了ABI接口变更的风险.部分编译选项会导致静态库/动态库的ABI变化或者行为变化,库的作者需要提供多个版本的库文件, 包括但不限于32/64bit, 静态/动态库, struct layout等不同组合.
Header Only规避了这个问题.

当然它的缺点也很明显.

1.变更会导致全部组件重新编译.这就要求Header Only Library尽量应为相对稳定的功能库,而不是做为接口库.
2.代码组织不合理时,编译时间会显著变长.大量使用Header Only Library需要合量划分编译单元,减少编译单元的数量
可以有效提高编译速度.就我的实践来看每个编译单元应大于1万行(不包括头文件).boost separated source

Header Only Library常被误解会导致编译后代码变大. 因为Header Only Library大量使用模板技术, 以增加灵活性,
模板是会一定程度上增加编译结果的大小. 排除这一点, Header Only Library不会导致编译后代码明显变大.原因主
要是编译器的优化起作用.Benchmards - Stackoverflow

  1. 大量的内联会增加代码编译的结果.
  2. 按需实例化会减少不用的代码链接到代码中.
  3. 死代码发现机制,会减少一部分不使用的代码.

如何创建Header Only Library

首先应选一个名字空间,比如 work4me,建议使用全小写,最好与web domain相同. 头文件中所有类,常量,函数,模板,枚举以及联合
都应在这个名字空间之内声明. 头文件也应放在同名目录之内, 且使用hpp做为后缀.

头文件中除了命名空间以外,只能包括:

  • 类/枚举/联合的声明和定义
  • 常量/常量表达式的声明和定义
  • 类模板,函数模板定义
  • typedef和using产生的名字.
  • 内联函数和内联成员函数的定义

建议提供一个fwd.hpp来放置所有模板的前置声明, 以及一些函数和函数模板的前置声明. 因为如果在模板声明中用到默认参数,用户就没有
办法写自己的模板前置声明.(默认模板参数只能在第一次声明时指定,且只能指定一次,那怕各处都保持一致也会编译失败).

特别需要注意所有函数定义,都需要加上inline关键字.

不能使用static定义任何全局的变量和函数.不能定义类的static变量成员,但可以定义内联的static成员函数.

不能使用匿名命名空间.如果需要向用户隐藏一些接口或类型,可以使用details/impl等表示实现的嵌套命名空间.

如果依赖标准库以外的第三方库,应在ReadMe中做出说明.

如果依赖平台库比如windows.h/pthread.h等平台专有库,可以考虑bridge模式把这实现部分放到win32,linux等嵌套命名空间下.

什么时候适用

Header Only Library适合通用类库,因为需求变动不大,对灵活性和效率要求较高.包括boost内这些语言工具,基础算法,基础工具.
不适合功能性比较强,需要减少耦合的地方.比如一些正交的功能模块.

做为折中,可以把功能模块本身写成Header Only Library,但使用一个编译单元把它与其它部分隔离.常用的隔离技术比如PIMPL可以在这里使用.

 

==============================================

本文转载于http://www.cnblogs.com/ahuangliang/p/cxx-practices-header-only-library.html

作者黄亮

以上是关于求STL(C++)模板库的set.h头文件的主要内容,如果未能解决你的问题,请参考以下文章

C++标准库与STL的关系

Header Only Library的介绍

初识STL

C++ 标准模板库STL 队列 queue 使用方法与应用介绍

开心档之C++ STL 教程

C++ STL详解