分享
 
 
 

[ 深入STL ] std::vector 的指针特化

王朝other·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

为了高效使用std::vector,我们有时候必须使用 std::vector<T*>,原因很多,为了支持多态,为了减小移动元素的代价,等等。使用不同类型的指针容器时,代码膨胀是必须要考虑的问题。我们希望所有的指针容器能共享同一份实现代码,这可以通过模板特化实现。

首先想到的是 vector<void*>,它如果能作为所有vector<T*>的基类,那剩下的问题就简单了。但是无法直接这样做,因为 void* 也是指针,它也试图利用vector<T*>实例化,所以你不能这样写:

template <class T>

class vector<T*> : private std::vector<void*>

{

//...

};

编译器会抱怨这个程序不能通过编译。vector<long>是一个无奈的选择,你得这样写:

template <class T>

class vector<T*> : private std::vector<long>

{

//...

};

大量的强制转换是需要的,但至少它可以运行。有没有更好的办法呢?Boost的disable_if手法显然可以帮助我们。它的定义很简单:

template <bool flag, typename T=void>

struct disable_if

{

typedef T type;

};

template <typename T>

struct disable_if<true,T>

{

};

我们还需要一个工具类,以判断一个T类型是不是void, 它的定义同样简单:

template <class U,class V>

struct is_same

{

static const bool value = false ;

};

template <class U>

struct is_same<U,U>

{

static const bool value = true;

};

现在我们可以这样写:

template <class T>

class vector<T*, typename disable_if<is_same<T,void>::value, std::allocator<T*> >::type>

: private std::vector<void*>

{

//..

};

OK,搞定了。如果希望使用特化的版本,加入这个实现文件的头文件,如果希望使用标准实现,去掉这个头文件就可以了。完整的程序如下:

namespace std{

template <class T>

class vector<T*,

typename disable_if<is_same<T,void>::value,

std::allocator<T*> >::type

>

: private std::vector<void*>

{

typedef std::vector<void*> base_t;

typedef vector<T*> self_t;

public:

typedef T element_type;

typedef T* value_type;

typedef value_type* pointer;

typedef const value_type* const_pointer;

typedef value_type* iterator;

typedef const value_type* const_iterator;

typedef value_type& reference;

typedef const value_type& const_reference;

typedef size_t size_type;

typedef ptrdiff_t difference_type;

typedef std::reverse_iterator<const_iterator>

const_reverse_iterator;

typedef std::reverse_iterator<iterator>

reverse_iterator;

typedef std::allocator<T*> allocator_type;

public:

allocator_type get_allocator() const

{ return allocator_type( base_t::get_allocator() ); }

iterator begin()

{ return iterator_cast(base_t::begin()); }

const_iterator begin() const

{ return iterator_cast(base_t::begin()); }

iterator end()

{ return iterator_cast(base_t::end()); }

const_iterator end() const

{ return iterator_cast(base_t::end()); }

reverse_iterator rbegin()

{ return reverse_iterator(end()); }

const_reverse_iterator rbegin() const

{ return const_reverse_iterator(end()); }

reverse_iterator rend()

{ return reverse_iterator(begin()); }

const_reverse_iterator rend() const

{ return const_reverse_iterator(begin()); }

using base_t::size;

using base_t::max_size;

using base_t::capacity;

using base_t::empty;

using base_t::reserve;

using base_t::pop_back;

using base_t::resize;

reference operator[](int index)

{

ASSERT( index>=0 && index<size()) ;

return reinterpret_cast<reference>(base_t::operator[](index));

}

const_reference operator[](int index) const

{

ASSERT( index>=0 && index<size()) ;

return reinterpret_cast<const_reference>(base_t::operator[](index));

}

vector() : base_t() {}

explicit vector(size_type n) : base_t(n) { }

vector(const self_t& rhs) : base_t(rhs) {}

self_t& operator=(const self_t& rhs)

{

base_t::operator=(rhs);

return *this;

}

template <class _InputIterator>

void assign(_InputIterator first, _InputIterator last)

{

base_t::assign(first,last);

}

reference front() { return *begin(); }

const_reference front() const { return *begin(); }

reference back() { return *(end() - 1); }

const_reference back() const { return *(end() - 1); }

void push_back(const_reference x)

{ base_t::push_back(x); }

void swap(self_t& x)

{ base_t::swap(x); }

iterator insert(iterator pos, const_reference x)

{

return iterator_cast(base_t::insert(

iterator_cast(pos),

x) );

}

iterator insert(iterator pos)

{ return this->insert(pos,0); }

template <class _InputIterator>

void insert(iterator __pos, _InputIterator __first, _InputIterator __last)

{

base_t::insert(iterator_cast(__pos),__first,__last);

}

void insert (iterator __pos, size_type __n, const_reference x)

{ base_t::insert(iterator_cast(__pos),__n,x); }

iterator erase(iterator pos)

{

return iterator_cast( base_t::erase(iterator_cast(pos)) );

}

iterator erase(iterator first, iterator last)

{

return iterator_cast(base_t::erase(

iterator_cast(first),

iterator_cast(last) ));

}

private:

iterator iterator_cast(typename base_t::iterator it) const

{

return iterator(&*it);

}

const_iterator iterator_cast(typename base_t::const_iterator it) const

{

return const_iterator(&*it);

}

typename base_t::iterator iterator_cast(iterator it) const

{

return &*it;

}

iterator iterator_cast(const_iterator it) const

{

return &*it;

}

};

} // std

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有