我是一个初学者,正在研究Stroustrup的书-《使用C ++编程原理和实践》(第二版)。
在第19.3.7章“泛化向量”中,我被困在以下几点:
在过去的章节中,我们创建了自己的向量类。 概括地说,使用模板。 对于模板,引入了默认类型,这些默认类型需要作为模板参数传递到类中。例如,调整向量的大小:
template<typename T> void vector<T>::resize(int newsize, T def = T());
要测试此方法是否有效,将创建该结构而不使用默认值:
struct No_default {
No_default(int); // only constructor for No_default
// ...
};
然后在书中将其初始化如下:
vector<No_default> v3;
v3.resize(100, No_default(2));
但是我得到这个错误:
no matching constructor for initialization of 'No_default[]'
T* p = new T[newalloc];
我将如何编写此结构,以便可以如上所示对其进行初始化?
这是自定义矢量类:
template<typename T>
class vector {
/*
invariant:
if 0 <= sz, elem[n] is element n
sz <= space
if sz < space, there is space for (space-sz) doubles after elem[sz-1]
*/
int sz;
T* elem;
int space;
public:
vector():sz{0}, elem{nullptr}, space{0} { };
explicit vector(int s);
vector(std::initializer_list<T>lst);
vector(const vector& v);
vector& operator=(const vector& v);
vector(vector&& v);
vector& operator=(vector&& v);
T& operator[](int n);
const T& operator[](int n) const;
~vector()
{
delete[] elem;
}
int size() const { return sz; }
int capacity() const { return space; }
void resize(int newsize, T def = T());
void push_back(const T& d);
void reserve(int newalloc);
};
template<typename T> vector<T>::vector(int s)
:sz{s},
elem{new T[s]},
space{s}
{
for (int i=0; i<s; ++i) elem[i]=0;
}
template<typename T> vector<T>::vector(std::initializer_list<T>lst)
:sz{int(lst.size())}, elem{new T[sz]}
{
std::copy(lst.begin(), lst.end(),elem);
}
template<typename T> vector<T>::vector(const vector& v)
:sz{v.sz}, elem{new T[v.sz]}
{
std::copy(v.elem, v.elem+sz, elem);
}
template<typename T> vector<T>& vector<T>::operator=(const vector& v)
{
if(this == &v) return *this;
if(v.sz<=space)
{
std::copy(v.elem, v.elem+sz, elem);
sz = v.sz;
return *this;
}
T* p = new T[v.sz];
std::copy(v.elem, v.elem+sz, p);
delete[] elem;
elem = p;
space = sz = v.sz;
return *this;
}
template<typename T> vector<T>::vector(vector&& v)
:sz{v.sz}, elem{v.elem}
{
v.sz = 0;
v.elem = nullptr;
}
template<typename T> vector<T>& vector<T>::operator=(vector&& v)
{
delete[] elem;
elem = v.elem;
sz = v.sz;
v.elem = nullptr;
v.sz = 0;
return *this;
}
template<typename T> T& vector<T>::operator[](int n)
{
return elem[n];
}
template<typename T> const T& vector<T>::operator[](int n) const
{
return elem[n];
}
template<typename T> void vector<T>::reserve(int newalloc)
{
if(newalloc<=space) return;
T* p = new T[newalloc];
for(int i=0; i<sz; ++i) p[i] = elem[i];
delete[] elem;
elem = p;
space = newalloc;
}
template<typename T>void vector<T>::resize(int newsize, T def)
{
reserve(newsize);
for(int i=sz; i<newsize; ++i) elem[i] = 0;
sz = newsize;
}
template<typename T> void vector<T>::push_back(const T& d)
{
if(space == 0) {
reserve(8);
} else if(sz==space) {
reserve(space*2);
}
elem[sz] = d;
++sz;
}
答案 0 :(得分:1)
似乎问题是这条线
template<typename T> void vector<T>::reserve(int newalloc)
{
if(newalloc<=space) return;
T* p = new T[newalloc];
从reserve
中调用 resize
,reserve
尝试默认构造T
。
您应该重新设计向量类,以便不会构造保留但尚未构成向量的元素。
您需要为此研究 placement new 。它使您可以将对象的分配与其构造分开。