使用C++的模板和std::any实现增删改查业务代码复用

概述

  • 在整理项目代码时,发现一个项目的封装挺有意思,摘取部分实现来说明。
  • 背景:项目中不同类型的结构体数据,分别有增、删、改、查的需求,而数据是存在std::vector中的,因此考虑使用C++的模板和std::any实现相关业务逻辑,以复用增删改查业务逻辑代码。
  • 这里涉及到一次数据格式转换,即auto&& vec = std::any_cast<std::vector&>(anyVec);

实现方法

// 生成id的方法类
class CIdGenerator
{
    
    
	CIdGenerator(){
    
    
		boost::uuids::uuid uuid = boost::uuids::random_generator()();
		m_id = boost::lexical_cast<string>(uuid);
	}
	const std::string& to_str() {
    
     return m_id; }

private:
	std::string m_id;
};


class CBaseObjectManager
{
    
    
public:
    CBaseObjectManager() = default;
    ~CBaseObjectManager()= default;
	
	// dst为需要返回T类型的对象(唯一标识符为id)
    template<typename T>
    int16_t GetObject(T& dst, const CIdGenerator& id, std::any anyVec)
    {
    
    
        int16_t ret = 0;

        auto&& vec = std::any_cast<std::vector<T>&>(anyVec);

        auto it = std::find_if(vec.begin(), vec.end(), [id](const T& t)
        {
    
    
            return t.GetId() == id;
        });

        if (it != vec.end())
        {
    
    
            dst = *it;
        }
        else
            ret = -1;

        return ret;
    }
	
	// anyVec为需要修改的数据,是std::vector<T>数组
    template<typename T>
    int16_t AddObject(const T& src, std::any&& anyVec)
    {
    
    
        int16_t ret = 0;

        ret = src.check();
        if (SuccessStatus != ret)
            return ret;

        auto&& vec = *(std::any_cast<std::vector<T>*>(anyVec));

        T t;
        auto find = GetObject(t, src.GetId(), vec);
        if (find == 0)
            return -1; // 已存在

        t = src;
        t.SetId(CIdGenerator());
        vec.push_back(t);

        return ret;
    }
	
	// anyVec为需要修改的数据,是std::vector<T>数组
    template<typename T>
    int16_t UpdateObject(const T& src, const CIdGenerator& id, std::any&& anyVec)
    {
    
    
        int16_t ret = 0;

        ret = src.check();
        if (SuccessStatus != ret)
            return ret;

        auto&& vec = *(std::any_cast<std::vector<T>*>(anyVec));

        auto it = std::find_if(vec.begin(), vec.end(), [id](const T& t)
        {
    
    
            return t.GetId() == id;
        });

        if (it != vec.end())
        {
    
    
            T src2 = src;
            auto& tmp = *it;
            std::swap(tmp, src2);
            tmp.SetId(id);
        }
        else
            ret = -1;

        return ret;
    }
	
	// anyVec为需要修改的数据,是std::vector<T>数组
    template<typename T>
    int16_t DeleteObject(const CIdGenerator& id, std::any&& anyVec)
    {
    
    
        int16_t ret = 0;

        auto&& vec = *(std::any_cast<std::vector<T>*>(anyVec));

        auto it = std::find_if(vec.begin(), vec.end(), [id](T& t)
        {
    
    
            return t.GetId() == id;
        });

        if (it != vec.end())
            vec.erase(it);
        else
            return -1;

        return ret;
    }

};

猜你喜欢

转载自blog.csdn.net/stallion5632/article/details/125825522