模板类接口,本质上就是套了层壳子
#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模板类警告