适配器简介
- adapter更像是一个换肤工程,如把参数的个数改一下或者把函数的名称改一下。
- 适配器根据它所改的对象分为三类
- 适配器更像是一个桥梁,只是修改接口,并不自己实现真正的功能
- 适配器都是用内含的方式实现对另一个东西的控制
容器适配器stack、queue
- 二者都内含了一个sequence,默认是deque。将容器的所有接口封装为个别的几个,或者将容器的接口封装后修改其名称
template <class T, class Sequence = deque<T>>
class stack{
...
public:
typedef typename Sequence::value_type value_type;
typedef typename Sequence::size_type size_type;
typedef typename Sequence::reference reference;
typedef typename Sequence::const_reference const_reference;
protected:
Sequence c;
public:
bool empty() const{ return c.empty(); }
size_type size() const { return c.size(); }
reference top() { return c.back(); }
const_reference top() const{ return c.back(); }
void push(const value_type& x) { c.push_back(x); }
void pop() { c.pop_back(); }
};
函数适配器
binder2nd
- 将传入的两个参数记下来,被调用时再实现绑定
- bind已经取代了bind2nd
template<class Operation>
class binder2nd
: public unary_function<typename Oprtation::first_argument_type,
typename Operation::result_type>{
protected:
Operation op;
typename Operation::second_argument_type value;
public:
binder2nd(const Operation& x, const typename Operation::second_argument_type& y):op(x), value(y){ }
typename Operation::result_type
operator()(const typename Operation::first_argument_type& x) const{
return op(x, value);
}
};
template<class Operation, class T>
inline binder2nd<Operation>bind2nd(const Operation& op, const T& x){
typedef typename Operation::second_argument_typee arg2_type;
return binder2nd<Operation>(op, arg2_type(x));
}
-------------------------使用-----------------------------
cout<< count_if(vi.begin(), vi.end(), (bind2nd(less<int>(), 40));
not1
template<class Predicate>
inline unary_negate<Predicate> not1(const Predicate& pred){
return unary_negate<Predicate>(pred);
}
template<class Predicate>
class unary_negate
:public unary_function<typename Predicate::argument_type, bool>{
protected:
Predicate pred;
public:
explicit unary_negate(const Predicate& x): pred(x){}
bool operator()(const typename Predicate::argument_type& x) const{
return !pred(x);
}
};
bind
- bind可以绑定
- functions
- function objects
- member functions,_1必须是某个对象的地址
- data members,_1必需是某个对象的地址
- 返回一个函数对象的引用
- bind可以指定模板参数,最多一个,表示的是返回类型
迭代器适配器
reverse_iterator
reverse_iterator rbegin()
{ return reverse_iterator(end()); }
reverse_iterator rend()
{ return reverse_iterator(begin()); }
template<class Iterator>
class reverse_iterator
{
protected:
Iterator current;
public:
typedef typename iterator_traits<Iterator>::iterator_category iterator_category;
typedef typename iterator_traits<Iterator>::value_type value_type;
...
typedef Iterator iterator_type;
typedef reverse_iterator<Iterator> self;
public:
explicit reverse_iterator(iterator_type x):current(x){}
reverse_iterator(const self& x):current(x.current){}
iterator_type base() const { return current; }
reference operator*() const { Iterator tmp = current; return *--tmp;}
pointer operator->() const { return &(operator*()); }
self& operator++() { --current; return *this;}
self& operator--() { ++current; return *this;}
self operator+(difference_type n) const { return self(current - n);}
self operator-(difference_type n) const { return self(current + b);}
};
inserter
- inserter是创建一块空间存储数据,而不是直接在一个空闲空间中赋值
- inserter可以实现在list中插入一个list
- advance是使迭代器前进3个位置
template<class Container, class Iterator>
inline insert_iterator<Container>
inserter(Container& x, Iterator i){
typedef typename Container::iterator iter;
return insert_iterator<Container>(x, i);
}
template<class Container>
class insert_iterator{
protected:
Container* container;
typename Container::iterator iter;
public:
typedef output_iterator_tag iterator_category;
insert_iterator(Container& x, typename Container::iterator i)
: container(&x(, iterator(i){}
insert_iterator<Container>&
operator=(const typename Container::value_type& value){
iter = container->insert(iter, value);
++iter;
return *this;
}
};
x适配器:ostream_iterator
- ostream_iterator不属于这三种迭代器
#include<iostreanm>
#include<iterator>
#include<vector>
#include<algorithm>
int main(){
std::vector<int> myvector;
for(int i=0; i<10; ++i) myvec.push_back(i*10);
std::ostream_iterator<int> out_it(std::cout, ",");
std::copy(myvector.begin(), myvector.end(), out_it);
return 0;
}
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator result)
{
while(first != last){
*result = *first;
++result; ++first;
}
return result;
}
template<class T, class charT=char, class traits=char_traits<charT>>
class ostream_iterator:
public iterator<output_iterator_tag, void, void, void, void>
{
basic_ostream<charT, traits>* out_stream;
const charT* delim;
public:
typedef charT char_type;
typedef traits traits_type;
typedef basic_ostream<charT, traits> ostream_type;
ostream_iterator(ostream_type& s): out_stream(&s), delim(0) {}
ostream_iterator(ostream_type& s, const charT* delimiter)
:out_stream(&s), delim(delimiter){}
ostream_iterator(const ostream_iterator<T, charT, traits>& x)
:out_stream(x.out_stream), delim(x.delim){}
~ostream_iterator(){}
ostream_iterator<T, charT, traits>& operator=(const T& value){
*out_stream<<value;
if(delim!=0) *out_stream<<delim;
return *this;
}
ostream_iterator<T, charT, traits>& operator*(){ return *this;}
ostream_iterator<T, charT, traits>& operator++(){ return *this;}
ostream_iterstor<T, charT, traits>& operator++(int){ return *this;}
x适配器:istream_iterator
#include<iostream>
#include<iterator>
int main()
{
double value1, value2;
std::cout<<"Please, insert two values:";
std::istream_iterator<double> eos;
std::istream_iterator<double> it(std::cin);
if(iit != eos) value1 = *iit;
++iit;
if(iit!=eos) value2 = *iit;
std::cout<<value1<<"*"<<value2<<"="
<<(value1*value2)<<endl;
return 0;
}
istream_iterator<int> iit(cin), eos;
copy(iit, eos, inserter(c, c.begin()));
template<class InputIterator, class OutputIterator>
OutputIterator copy(InputIteratornfirst, InputIterator result)
{
while(first != last){
*result = *first;
++result; ++first;
}
return result;
}
template<class T, class charT=char, class traits = char_traits<charT>, class Distance = ptrdiff_t>
class istream_iterator:
public iterator<input_iterator_tag, T, Distance, const T*, const T&>
{
basic_istream<charT, traits>* in_stream;
T value;
public:
typedef charT char_type;
typedef traits traits_type;
typedef basic_istream<charT, traits> istream_type;
istream_iterator():in_stream(0){}
istream_iterator(istream_type& s):in_stream(&s){++*this; }
istream_iterator(const istream_iterator<T, charT, traits, Distance>& x):in_stream(x.in_stream), value(x.value){}
~istream_iterator(){}
const T& operator*() const { return value;}
const T* operator->() const { return &value;}
istream_iterator<T, charT, traits, Distance>& operator++(){
if(in_stream&& !(*in_stream>>value)) in_stream = 0;
return *this;
}
istream_iterator<T, charT, traits, Distance> operator++(int){
istream_iterator<T, charT, traits, Distance> tmp = *this;
++*this;
return tmp;
}
};