Programming Priciples and Practice Using C++ Chapter 17-19 を読んでいて、自分のバージョンの Vector を書こうとしています。これは私のコードです:
#include <stdexcept>
#include <exception>
using namespace std;
struct Range_error:out_of_range{
int index;
Range_error(int i):out_of_range("Range error"),index(i){}
};
template<class T, class A = allocator<T>> struct Vector_base{
A alloc;
T* elem;
int sz; // number of elements
int space; // number of elements plus "free space"/"slots" for new elements("the current allocation")
void copy(const Vector_base& arg)
{
T* p = alloc.allocate(arg.sz);
for(int i=0; i<arg.sz; ++i) alloc.construct(&p[i], arg.elem[i]);
elem = p;
sz = arg.sz;
space = arg.space;
};
Vector_base(): elem(alloc.allocate(0)), sz(0), space(0) {};
Vector_base(int n):elem(alloc.allocate(n)), sz(n), space(n) {};
Vector_base(const A& a, int n):alloc(a), elem(a.allocate(n)), sz(n), space(n){};
Vector_base(const Vector_base& arg) {copy(arg);}
~Vector_base() {alloc.deallocate(elem, space);}
};
template<class T, class A = allocator<T>> class Vector : private Vector_base<T,A>{
public:
Vector() : Vector_base(){};
Vector(int n) : Vector_base(n) {for(int i=0; i<this->sz; ++i) this->alloc.construct(&this->elem[i], T());}
Vector(const Vector& arg) : Vector_base(arg) {};
Vector& operator=(const Vector&);
~Vector() {};
int size() const {return this->sz;}
int capacity() const {return this->space;}
void resize(int newsize, T val=T());
void push_back(const T& val);
void pop_back(); // delete the last element
void reserve(int newalloc);
T& operator[](unsigned int n)
{
return this->elem[n];
}
const T& operator[](unsigned int n) const
{
return this->elem[n];
}
T& at(unsigned int n)
{
if(n<0 || this->sz<=n) throw Range_error(n);
return this->elem[n];
}
const T& at(unsigned int n) const
{
if(n<0 || this->sz<=n) throw Range_error(n);
return this->elem[n];
}
};
template<class T, class A> void Swap(Vector_base<T,A>& a, Vector_base<T,A>& b){
Vector_base<T,A> c(a);
a=b;
b=c;
}
template<class T, class A> Vector<T,A>& Vector<T,A>::operator=(const Vector<T,A>& a)
{
if(this == &a) return *this; // self-assignment, no work needed
if(a.sz<=sz){
for(int i=0; i<a.sz; ++i) elem[i] = a.elem[i];
sz=a.sz;
return *this;
}
T* p = new T[a.sz];
for(int i=0; i<a.sz; ++i) p[i] = a.elem[i];
delete elem;
elem=p;
space=sz = a.sz;
return *this;
}
template<class T, class A> void Vector<T,A>::reserve(int newalloc)
{
if(newalloc <= this->space) return;
Vector_base<T,A> b(this->alloc,newalloc);
for(int i=0; i<this->sz; ++i) this->alloc.construct(&b.elem[i], this->elem[i]); // copy
for(int i=0; i<this->sz; ++i) this->alloc.destroy(&this->elem[i]);
Swap<Vector_base<T,A>>(*this, b);
this->space = newalloc;
}
template<class T, class A> void Vector<T,A>::resize(int newsize, T val=T())
{
reserve(newsize);
for(int i=this->sz; i<newsize; ++i) this->alloc.construct(&this->elem[i], val);
for(int i=newsize; i<this->sz; ++i) this->alloc.destroy(&this->elem[i]);
this->sz = newsize;
}
template<class T, class A> void Vector<T,A>::push_back(const T& val)
{
if(this->space == 0) reserve(8);
else if(this->sz == this->space) reserve(2*(this->space));
this->alloc.construct(&this->elem[this->sz], val);
++(this->sz);
}
template<class T, class A> void Vector<T,A>::pop_back()
{
if(this->sz == 0) return;
this->alloc.destroy(&this->elem[--(this->sz)]);
if(this->sz <= (this->space)/2)
{
Vector_base<T,A> b(this->alloc,(this->space)/2);
for(int i=0; i<this->sz; ++i) this->alloc.construct(&b.elem[i], this->elem[i]); // copy
for(int i=0; i<this->sz; ++i) this->alloc.destroy(&this->elem[i]);
Swap<Vector_base<T,A>>(*this, b);
this->space /= 2;
}
}
コンパイルすると、vc++ は「void Swap(Vector_base &,Vector_base &)」: 「Vector」から「Vector_base,A> &」のテンプレート引数を推測できませんでした」と表示します。*this は Vector オブジェクトですが、b は Vector_base オブジェクトであることは知っていますが、本にはそう書かれています。このコードを機能させるにはどうすればよいですか? このコードのメモリリークはありますか? ありがとう!