没有用于初始化'No_default []'

时间:2018-12-07 10:37:39

标签: c++ templates vector initialization

我是一个初学者,正在研究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;
}

1 个答案:

答案 0 :(得分:1)

似乎问题是这条线

template<typename T> void vector<T>::reserve(int newalloc)
{
    if(newalloc<=space) return;
    T* p = new T[newalloc];
reserve中调用

resizereserve尝试默认构造T

您应该重新设计向量类,以便不会构造保留但尚未构成向量的元素。

您需要为此研究 placement new 。它使您可以将对象的分配与其构造分开。