нет подходящего конструктора для инициализации 'No_default []' - PullRequest
0 голосов
/ 07 декабря 2018

Я новичок и работаю над книгой Страуструпа - Принципы и практика программирования на C ++ (2-е издание).

В главе 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 голосов
/ 07 декабря 2018

Кажется, проблема в том, что эта строка

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

reserve вызывается из resize, а reserve пытается создать конструкцию по умолчанию T.

Вы должны изменить свой векторкласс, чтобы элементы, которые зарезервированы, но еще не являются частью вектора, не были сконструированы.

Для этого вам нужно исследовать размещение нового .Это позволяет отделить выделение объектов от их построения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...