在dll中使用STL模板类作为接口类的成员实例

模板类接口,本质上就是套了层壳子

#define FREE_PTR(data) do{if((data)!=nullptr) {delete (data); (data)=nullptr;}}while(0)

template<class _Tp> class __declspec(dllexport) STLApi
{
public:
	using _Ty = typename _Tp::value_type;
	using size_type = typename _Tp::size_type;
	using difference_type = typename _Tp::difference_type;
	using iterator = typename _Tp::iterator;
	using const_iterator = typename _Tp::const_iterator;
	using reverse_iterator = typename _Tp::reverse_iterator;
	using const_reverse_iterator = typename _Tp::reverse_iterator;
	using allocator_type = typename _Tp::allocator_type;

	explicit STLApi() : stldata(new _Tp) {}
	STLApi(std::initializer_list<_Ty> _Ilist) : stldata(new _Tp(_Ilist)) {}
	STLApi(const _Tp &api) : stldata(new _Tp(api)) {}
	STLApi(const STLApi& api) : stldata(new _Tp(api)) { *this = api; }
	~STLApi() { FREE_PTR(stldata); }
	iterator begin()noexcept { return stldata->begin(); }
	const_iterator begin()const noexcept { return stldata->begin(); }
	iterator end()noexcept { return stldata->end(); }
	const_iterator end()const noexcept { return stldata->end(); }
	iterator erase(const_iterator _Where) { return stldata->erase(_Where); }
	iterator erase(const_iterator _First, const_iterator _Last) { return stldata->erase(_First, _Last); }
	iterator insert(const_iterator _Where, _Ty&& _Val) { return stldata->insert(_Where, _Val); }
	iterator insert(const_iterator _Where, const _Ty& _Val) { return stldata->insert(_Where, _Val); }
	iterator insert(const_iterator _Where, const size_type _Count, const _Ty& _Val) { return stldata->insert(_Where, _Count, _Val); }
	iterator insert(const_iterator _Where, std::initializer_list<_Ty> _Ilist) { return stldata->insert(_Where, _Ilist); }

	void assign(std::initializer_list<_Ty> _Ilist) { stldata->assign(_Ilist); }
	void assign(const size_type _Newsize, const _Ty& _Val) { stldata->assign(_Newsize, _Val); }
	template<class _Iter, class = enable_if_t<_Is_iterator_v<_Iter>>> void assign(_Iter _First, _Iter _Last) { stldata->assign(_First, _Last); }
	_Ty& at(const size_type _Pos) { return stldata->at(_Pos); }
	const _Ty& at(const size_type _Pos)const { return stldata->at(_Pos); }
	_Ty& back() { return stldata->back(); }
	const _Ty& back() const { return stldata->back(); }
	size_type capacity() const noexcept { return stldata->capacity(); }
	const_iterator cbegin() const noexcept { return stldata->cbegin(); }
	const_iterator crend() const noexcept { return stldata->cbegin(); }
	void clear() noexcept { stldata->clear(); }
	_Ty * data() noexcept { return stldata->data(); }
	const _Ty * data()const noexcept { return stldata->data(); }
	bool empty()const noexcept { return stldata->empty(); }
	template<class... _Valty> iterator emplace(const_iterator _Where, _Valty&&... _Val) { return stldata->emplace(_Where, _Val); }
	template<class... _Valty> decltype(auto) emplace_back(_Valty&&... _Val) { return stldata->emplace_back(_Val); }
	_Ty& front() { return stldata->front(); }
	const _Ty& front() const { return stldata->front(); }
	allocator_type get_allocator() const noexcept { return stldata->get_allocator(); }
	size_type max_size() const noexcept { return stldata->max_size(); }
	void pop_back() { stldata->pop_back(); }
	void push_back(_Ty && val) { stldata->push_back(val); }
	void push_back(const _Ty & val) { stldata->push_back(val); }
	reverse_iterator rbegin() noexcept { return stldata->rbegin(); }
	const_reverse_iterator rbegin() const noexcept { return stldata->rbegin(); }
	reverse_iterator rend() noexcept { return stldata->rend(); }
	const_reverse_iterator rend() const noexcept { return stldata->rend(); }
	void resize(const size_type len)noexcept { stldata->resize(len); }
	void reserve(const size_type _Newcapacity) { stldata->reserve(_Newcapacity); }
	void shrink_to_fit() { stldata->shrink_to_fit(); }
	size_type size() const noexcept { return stldata->size(); }
	void swap(_Tp &api)noexcept { stldata->swap(api); }
	void swap(STLApi &api)noexcept { stldata->swap(*(api.stldata)); }

	_Ty& operator [](const size_type idx) { return (*stldata)[idx]; }
	const _Ty& operator [](const size_type idx)const { return (*stldata)[idx]; }

	_Tp& operator *() noexcept { return *stldata; }
	const _Tp& operator * ()const noexcept { return *stldata; }
	_Tp* d_ptr() noexcept { return stldata; }
	const _Tp* d_ptr()const noexcept { return stldata; }
	_Tp& obj() noexcept { return *stldata; }
	const _Tp& obj()const noexcept { return *stldata; }
	operator _Tp& () { return *stldata; }
	operator const _Tp& ()const { return *stldata; }

	constexpr bool operator == (const _Tp& api) const noexcept { return *this == api; }
	constexpr bool operator != (const _Tp& api) const noexcept { return *this != api; }
	constexpr bool operator > (const _Tp& api) const noexcept { return *this > api; }
	constexpr bool operator < (const _Tp& api) const noexcept { return *this < api; }
	constexpr bool operator >= (const _Tp& api) const noexcept { return *this >= api; }
	constexpr bool operator <= (const _Tp& api) const noexcept { return *this <= api; }
	constexpr bool operator + (const _Tp& api) const noexcept { return *this + api; }
	STLApi& operator = (const STLApi& api)noexcept {
		if (this == &api)return *this;
		if (stldata != nullptr && api.stldata != nullptr)
			*stldata = *api.stldata;
		return *this;
	}
	STLApi& operator = (const _Tp& api)noexcept {
		if (stldata == &api)return *this;
		if (stldata != nullptr)
			*stldata = api;
		return *this;
	}
private:
	_Tp *stldata;
};
template<typename _Tp> static inline std::ostream & operator << (std::ostream &out, const STLApi<_Tp> &api)
{
	out << api.obj();
	return out;
}

使用案例

#ifdef EXPORTS
#define API __declspec(dllexport)
#else 
#define API __declspec(dllimport)
#endif

class API MyClass
{
public:
	explicit MyClass() : vec({ 0,1,2,3,4,5,6,7,8,9,10 }) {}
	void sort()
	{
		std::sort(vec.begin(), vec.end(), [](const double &a, const double &b) {return a > b; });
	}
	void print()
	{
		std::cout << name << std::endl;
		for (double i : vec)
			std::cout << i << " ";
		std::cout << endl;
	}
private:
	STLApi<std::vector<double>> vec;
	STLApi<std::string> name;
};

编译不会出现STL模板类警告

你可能感兴趣的:(c++,dll,动态库,STL模板类)