关于STL vector的实现 答对加100
vector其中有两个构造函数template<class_Iter>vector(_Iter_First,_Iter_Last)使用两个迭代器做参数的模板函数和vect...
vector其中有两个构造函数
template<class _Iter>
vector(_Iter _First, _Iter _Last) 使用两个迭代器做参数的模板函数
和
vector(size_type _Count, const _Ty& _Val)size_t数量个val值
现在我想自己实现一个符合标准的vector,在使用整数做元素时却碰上冲突问题,比如使用myvector<int> v(3, 1)实际上会调用前者而非后者而引发错误.有人告诉我用myvector<int> v(static_cast<size_t>(3), 1),但标准库确实不需要通过任何类型转换就能通过编译,请问这个问题应该怎么解决呢?我看了dev-c++的头文件,里面通过在第一个函数内部使用一个模板类来保证其参数为非整数,请问他是怎么做到的?因为询问多次未果先上50,给出确实能实现的方案加100,如能给出完整源码或语法相关的资料可以再加
谢谢pur_e的回答,你的实现很有意思,有时间我会研究一下的.但我还是坚持我模板函数的说法,这是我从DEV-C++ 4.9.9.2 的头文件stl_vector.h里摘的
/*** @brief Builds a %vector from a range. * @param first An input iterator. * @param last An input iterator.
*
* Create a %vector consisting of copies of the elements from
* [first,last). ...
**/
template<typename _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
}
注意,_InputIterator是个模板参数,而不是确定类型.还有函数体里第一行的注释"检查这是否为整数类型,如果是,这就不是一个迭代器."在VC++里也是这样.我想要的就是_Is_integer这个模板类的实现方法.不过还是非常感谢你,如果没别人答的话,我会给你加100分的.希望多交流 展开
template<class _Iter>
vector(_Iter _First, _Iter _Last) 使用两个迭代器做参数的模板函数
和
vector(size_type _Count, const _Ty& _Val)size_t数量个val值
现在我想自己实现一个符合标准的vector,在使用整数做元素时却碰上冲突问题,比如使用myvector<int> v(3, 1)实际上会调用前者而非后者而引发错误.有人告诉我用myvector<int> v(static_cast<size_t>(3), 1),但标准库确实不需要通过任何类型转换就能通过编译,请问这个问题应该怎么解决呢?我看了dev-c++的头文件,里面通过在第一个函数内部使用一个模板类来保证其参数为非整数,请问他是怎么做到的?因为询问多次未果先上50,给出确实能实现的方案加100,如能给出完整源码或语法相关的资料可以再加
谢谢pur_e的回答,你的实现很有意思,有时间我会研究一下的.但我还是坚持我模板函数的说法,这是我从DEV-C++ 4.9.9.2 的头文件stl_vector.h里摘的
/*** @brief Builds a %vector from a range. * @param first An input iterator. * @param last An input iterator.
*
* Create a %vector consisting of copies of the elements from
* [first,last). ...
**/
template<typename _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type())
: _Base(__a)
{
// Check whether it's an integral type. If so, it's not an iterator.
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_dispatch(__first, __last, _Integral());
}
注意,_InputIterator是个模板参数,而不是确定类型.还有函数体里第一行的注释"检查这是否为整数类型,如果是,这就不是一个迭代器."在VC++里也是这样.我想要的就是_Is_integer这个模板类的实现方法.不过还是非常感谢你,如果没别人答的话,我会给你加100分的.希望多交流 展开
展开全部
今天看了下源码,确实是通过判断是否是int类型进行不同操作的,具体如下:
首先是这个函数:
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type()) : _Base(__a) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_aux(__first, __last, _Integral());
}
定义了一个类型:
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
这个类型会根据_InputIterator的不同而进行不一样的类模板显示具体化,比如说,如果是int类型的话,
__STL_TEMPLATE_NULL struct _Is_integer<int> {
typedef __true_type _Integral;
};
会将__true_type定义为_Integral,其他非数值情况,会用默认的模板实例化:
template <class _Tp> struct _Is_integer {
typedef __false_type _Integral;
};
会将__false_type定义为_Integral
然后调用:
_M_initialize_aux(__first, __last, _Integral());
_M_initialize_aux这个函数有重载,会根据_Integral()是__false_type还是__true_type调用不同的重载函数,
两个重载如下:
template <class _Integer>
void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
_M_start = _M_allocate(__n);
_M_end_of_storage = _M_start + __n;
_M_finish = uninitialized_fill_n(_M_start, __n, __value);
}
template <class _InputIterator>
void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
__false_type) {
_M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
}
之后的就简单了,就是根据是否是int做出不同的操作就是了
======================================================================
我看的是vc的vector文件,有点不太一样,呵呵
是我想当然了,确实是用模板类的,不过写的挺麻烦的、
你可以到网上搜一下stl的源码,然后用Source Insight这个软件跟踪一下
还是看源码最容易理解,我也得看一下了,不懂的还是很多啊
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
这样说也有点不明白,给你写了个简单点的,代码如下,我只是写个简单的例子,迭代器的实现很麻烦的:
#include <iostream>
using namespace std;
class _It
{
public:
_It(){}
_It(int *a):p(a){}
int* operator ++(int)
{
int *q=p;
p++;
return q;
}
bool operator <=(_It &oth)
{
return (this->p)<=(oth.p);
}
int operator -(_It &oth)
{
return (this->p)-(oth.p);
}
private:
int *p;
};
template<class T>
class myvector
{
public:
myvector(int n,T a)
{
data=new T[n];
for(int i=0;i<n;i++)
data[i]=a;
len=n;
}
myvector(_It s,_It e)
{
len=e-s;
data=new T[len];
T *p=data;
while(s<=e)
*p++=*s++;
}
void print()
{
for(int i=0;i<len;i++)
cout<<data[i]<<" ";
cout<<endl;
}
private:
T *data;
int len;
};
void main()
{
myvector<int> v1( 5, 6 );
v1.print();
int a[] = {1,2,3};
myvector<int> v2(a, a+3);
v2.print();
}
==============================================================
int a[] = {1,2,3}; vector<int> v(a, a+3);
这种实现不是因为模板,而是因为int *这种指针也是迭代器的一种,就是说
int *可以转化为迭代器,而不是因为模板的类型替换
比如说
class A
{
A(int){}
}
这样的类,是可以这样用的:
如果一个函数的定义是:
void func(A x){}
则调用时可以用:
func(5);
因为A中有转换的构造函数
这里也是一样的,可以用
int a[] = {1,2,3}; vector<int> v(a, a+3);
是因为int *可以转化为迭代器,
不知道这样说明白了没有
其实我对stl的机制也有很多不明白的
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vector里面template中的参数和迭代器不是一个吧,如下:
template<class _Ty, class _A = allocator<_Ty> >
typedef const_iterator _It;
vector(_It _F, _It _L, const _A& _Al = _A())
差不多这个意思:
template<class T>
vector(_Iter _First, _Iter _Last)
不会报错
首先是这个函数:
template <class _InputIterator>
vector(_InputIterator __first, _InputIterator __last,
const allocator_type& __a = allocator_type()) : _Base(__a) {
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
_M_initialize_aux(__first, __last, _Integral());
}
定义了一个类型:
typedef typename _Is_integer<_InputIterator>::_Integral _Integral;
这个类型会根据_InputIterator的不同而进行不一样的类模板显示具体化,比如说,如果是int类型的话,
__STL_TEMPLATE_NULL struct _Is_integer<int> {
typedef __true_type _Integral;
};
会将__true_type定义为_Integral,其他非数值情况,会用默认的模板实例化:
template <class _Tp> struct _Is_integer {
typedef __false_type _Integral;
};
会将__false_type定义为_Integral
然后调用:
_M_initialize_aux(__first, __last, _Integral());
_M_initialize_aux这个函数有重载,会根据_Integral()是__false_type还是__true_type调用不同的重载函数,
两个重载如下:
template <class _Integer>
void _M_initialize_aux(_Integer __n, _Integer __value, __true_type) {
_M_start = _M_allocate(__n);
_M_end_of_storage = _M_start + __n;
_M_finish = uninitialized_fill_n(_M_start, __n, __value);
}
template <class _InputIterator>
void _M_initialize_aux(_InputIterator __first, _InputIterator __last,
__false_type) {
_M_range_initialize(__first, __last, __ITERATOR_CATEGORY(__first));
}
之后的就简单了,就是根据是否是int做出不同的操作就是了
======================================================================
我看的是vc的vector文件,有点不太一样,呵呵
是我想当然了,确实是用模板类的,不过写的挺麻烦的、
你可以到网上搜一下stl的源码,然后用Source Insight这个软件跟踪一下
还是看源码最容易理解,我也得看一下了,不懂的还是很多啊
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
这样说也有点不明白,给你写了个简单点的,代码如下,我只是写个简单的例子,迭代器的实现很麻烦的:
#include <iostream>
using namespace std;
class _It
{
public:
_It(){}
_It(int *a):p(a){}
int* operator ++(int)
{
int *q=p;
p++;
return q;
}
bool operator <=(_It &oth)
{
return (this->p)<=(oth.p);
}
int operator -(_It &oth)
{
return (this->p)-(oth.p);
}
private:
int *p;
};
template<class T>
class myvector
{
public:
myvector(int n,T a)
{
data=new T[n];
for(int i=0;i<n;i++)
data[i]=a;
len=n;
}
myvector(_It s,_It e)
{
len=e-s;
data=new T[len];
T *p=data;
while(s<=e)
*p++=*s++;
}
void print()
{
for(int i=0;i<len;i++)
cout<<data[i]<<" ";
cout<<endl;
}
private:
T *data;
int len;
};
void main()
{
myvector<int> v1( 5, 6 );
v1.print();
int a[] = {1,2,3};
myvector<int> v2(a, a+3);
v2.print();
}
==============================================================
int a[] = {1,2,3}; vector<int> v(a, a+3);
这种实现不是因为模板,而是因为int *这种指针也是迭代器的一种,就是说
int *可以转化为迭代器,而不是因为模板的类型替换
比如说
class A
{
A(int){}
}
这样的类,是可以这样用的:
如果一个函数的定义是:
void func(A x){}
则调用时可以用:
func(5);
因为A中有转换的构造函数
这里也是一样的,可以用
int a[] = {1,2,3}; vector<int> v(a, a+3);
是因为int *可以转化为迭代器,
不知道这样说明白了没有
其实我对stl的机制也有很多不明白的
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
vector里面template中的参数和迭代器不是一个吧,如下:
template<class _Ty, class _A = allocator<_Ty> >
typedef const_iterator _It;
vector(_It _F, _It _L, const _A& _Al = _A())
差不多这个意思:
template<class T>
vector(_Iter _First, _Iter _Last)
不会报错
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询