c++惰性计算简单实现

61 阅读1分钟

先正常的实现一个的vec类

#include<algorithm>
#include<initializer_list>

template<class T>
class Vec {
public:
	using dataType = T;
private:
	using ptr_t = T*;
	using size_t = std::size_t;
	using list_t = std::initializer_list<T>;
private:
	ptr_t  _Ptr;
	size_t _Size;
public:
	Vec() :
		_Ptr(nullptr),
		_Size(0)
	{}

	Vec(list_t list) {
		_Size = list.size();
		_Ptr = new T[_Size];
		auto iter = list.begin();
		for (size_t i = 0; i < _Size; ++i) {
			_Ptr[i] = *iter;
			++iter;
		}
	}
	Vec(size_t size) {
		_Ptr = new T[size];
		_Size = size;
		std::fill(_Ptr, _Ptr + _Size, 0);
	}
	Vec(size_t size,T val) {
		_Ptr = new T[size];
		_Size = size;
		std::fill(_Ptr, _Ptr + _Size, val);
	}
	Vec(const Vec& other) {
		_Ptr = new T[other._Size];
		_Size = other._Size;
		std::copy(other._Ptr, other._Ptr + other._Size, _Ptr);
	}
	Vec(Vec&& other)noexcept {
		_Ptr = other._Ptr;
		_Size = other._Size;
		other._Ptr = nullptr;
	}

	T& operator[](size_t pos) {
		return _Ptr[pos];
	}
	const T& operator[](size_t pos)const {
		return _Ptr[pos];
	}
	Vec& operator =(const Vec& other){
		if (&other == this)return *this;
		if (_Ptr != nullptr)delete[] _Ptr;

		_Ptr = new T[other._Size];
		_Size = other._Size;
		std::copy(other._Ptr, other._Ptr + other._Size, _Ptr);
	}
	Vec& operator =(Vec&& other)noexcept {
		if (&other == this)return *this;
		if (_Ptr != nullptr)delete[] _Ptr;

		_Ptr = other._Ptr;
		_Size = other._Size;
		other._Ptr = nullptr;
	}
	_NODISCARD  constexpr size_t size()const {
		return _Size;
	}
	~Vec() {
		if (_Ptr != nullptr) delete[] _Ptr;
	}
};

之后使用wrapper层封装

template<class L, class R>
class Add {
public:
	static_assert(std::is_same_v<typename L::dataType, typename R::dataType>);
	using dataType = typename L::dataType;
private:
	const L& _Lhs;
	const R& _Rhs;
	size_t _Size;
public:
	Add() = delete;
	explicit Add(const L& lhs, const R& rhs) :
		_Lhs(lhs), _Rhs(rhs) {
		if (lhs.size() != rhs.size()) {
			throw("size not match");
		}
		_Size = _Lhs.size();

	}
	_NODISCARD  constexpr size_t size()const {
		return _Size;
	}
	const typename L::dataType operator[](size_t pos)const {
		return _Lhs[pos] + _Rhs[pos];
	}
	Vec<dataType> toVec() {
		Vec<dataType> vec(_Size);
		for (size_t i = 0; i < _Size; ++i) {
			vec[i] = this->operator[](i);
		}
		return vec;
	}
};

template<class L, class R>
Add<L, R> operator+(const L& lhs, const R& rhs) {
	return Add<L, R>(lhs, rhs);
}

调用的话虽然略抽象

#include<iostream>
#include"vec.h"
using namespace std;

int main() {
	Vec<float> a0 = { 1,2,3,4 };
	Vec<float> a1 = { 1,2,3,4 };
	Vec<float> a2 = { 1,2,3,4 };
	Vec<float> a3 = { 1,2,3,4 };

	auto a4 = a0 + a1 + a2 + a3;
	//Add<Add<Add< Vec<float>, Vec<float>>, Vec<float>>, Vec<float>> t = a4;
	Vec<float> fmt_a = a4.toVec();

	for (int i = 0; i < 4; i++) {
		cout << a4[i] << " " << fmt_a[i] << endl;
	}
}

其实想实现的是惰性矩阵乘,但是没有比较好的方法,这种写法可以有效减少内存消耗