Экзамен С++ 2019


#21

Написал вот такой код, а он с стандартным copy работать не хочет, что-то страшное вылетает. Скажите пожалуйста, это норма, что мой итератор не подходит для STL? С написанным мной copy работает всё работает.

template<typename T>
class myvector_itetator
{
	T* p;
public:
	myvector_itetator(T* pp) :p(pp) {};

	T& operator *()
	{
		return *p;
	}
	myvector_itetator<T>& operator++()
	{
		++p;
		return *this;
	}
	myvector_itetator<T> operator++(int)
	{
		myvector_itetator<T> it = *this;
		++p;
		return it;
	}


	bool operator!=(const myvector_itetator<T>& it)
	{
		return it.p != p;
	}
};


template<typename T>
class myvector
{
	
	

	T* data;
	int sz;
public:

	
explicit	myvector( int s,T t=T()) :sz(s)
	{
		data = new T[sz];
		fill(data, data + sz, t);
	}
	/*

	myvector() :sz(0)
	{
		data = new T[sz];
	}

	*/
	myvector() = default;
	
	void swap(myvector<T>& v)
	{
		std::swap(data, v.data);
		std::swap(sz, v.sz);
	}

	T& operator[](int i) const
	{
	
		if (i >= 0 && i < sz)
			return data[i];
		else
			throw i;
	
	}


	myvector(const myvector<T>& v)
	{
		cout <<endl<< "KK" << endl;
		sz = v.sz;
		data = new T[sz];
		copy(v.data, v.data + sz, data);
	}

	myvector( myvector<T>&& v):myvector()
	{
		cout << endl << "move KK" << endl;
		swap(v);
	
	}
	myvector<T>& operator=(const myvector<T>& v)
	{
		cout << endl << "=" << endl;
		if (this != &v)
		{
			
			delete data;
			sz = v.sz;
			data = new T[sz];
			copy(v.data, v.data + sz, data);
		}
		return *this;
	}

	myvector<T>& operator=( myvector<T>&& v)
	{
		/*
		cout<< endl<< "move =" << endl;
		delete data;
		sz = v.sz;
		data = v.data;
		v.data = nullptr;
		*/
		swap(v);
		return *this;
	}

	friend ostream& operator<<(ostream &os, const myvector<T>& v)
	{
		cout << '[';
		for (int i = 0; i < v.sz; i++)
			cout << v[i] << ' ';
		cout << ']' << endl;
		return os;
	}

	myvector_itetator<T> begin()
	{
		return myvector_itetator<T>(data);
	}

	myvector_itetator<T> end()
	{
		return myvector_itetator<T>(data+sz);
	}

	~myvector()
	{
		if(data!=nullptr)
		  delete[] data;
	}

	
	
	friend myvector<T> operator +(const myvector<T>& v1, const myvector<T>& v2)
	{
		int sz = v1.sz;
		myvector<T> res(sz);
		for (int i = 0; i < sz; i++)
			res[i] = v1[i] + v2[i];
		return res;
	}



};

#22

Да, я на консультации отвечал. В стандартном немного сложнее.

Здесь важно понимание идеи.


#23

Да, это ошибка. Исправил.


#24

Исправил. Спасибо. Закачал новую версию. Вот верный код:

myvector<T>& operator=(myvector<T>&& v)
  {
    delete [] data;
    sz = v.sz;
    data = v.data;
    v.data = nullptr;
    return *this;
  }

#25

По договорённости со старостой экзамен 9 января начнётся в 9.00.


#26

В задании, где мы описываем back_inserter_iterator, operator= не хочет воспринимать (C::value_type x) в качестве параметра и, соответственно, код не компилируется.

template<typename C>
struct back_inserter_iterator
{
	C& c;
	back_inserter_iterator(C& _c) : c(_c) {}
	back_inserter_iterator<C>& operator*()
{
	return *this;
}
void operator=(C::value_type x)
{
	c.push_back(x);
}
void operator++() {}
};

template<typename C >
inline back_inserter_iterator<C> my_back_inserter(C& c)
{
	return back_inserter_iterator<C>(c);
}

#27

Получается скомпилировать только такой код:

template<typename T, typename C >
struct back_inserter_iterator
{
    C& c;
    back_inserter_iterator(C& _c) : c(_c) {}
    back_inserter_iterator<T, C>& operator*()
    {
	    return *this;
    }
    void operator=(T x)
    {
	    c.push_back(x);
    }
    void operator++() {}
};

template<typename T, typename C >
inline back_inserter_iterator<T, C> my_back_inserter(C& c)
{
    return back_inserter_iterator<C::value_type, C>(c);
}

#28

Да, компилятор не может распознать в записи C::value_type имя типа. Надо ему помочь и явно подсказать:

template<typename C>
struct back_inserter_iterator
{
	C& c;
	back_inserter_iterator(C& _c) : c(_c) {}
	back_inserter_iterator<C>& operator*()
	{
		return *this;
	}
	void operator=(typename C::value_type x)
	{
		c.push_back(x);
	}
	void operator++() {}
};

template<typename C >
inline back_inserter_iterator<C> my_back_inserter(C& c)
{
	return back_inserter_iterator<C>(c);
}

Про “загадочный” typename можно почитать вот здесь: