赞
踩
在开发过程中,在写一些回调函数的过程中,常常希望参数是不确定、可变的,这个时候我就希望能有一个参数包,各种参数都可以塞到参数包里面,然后将该参数包作为一个参数。
之前一直使用tuple或结构体指针来实现该功能,但这两者在使用过程中还是有些不方便,于是就想自己写一个参数包的类。
在boost库中有一个any类型,可作为参数包中参数的载体,可自行从boost中摘抄过来。我这边也提供一份代码:
- #ifndef class_any
- #define class_any
-
- #include <typeinfo>
-
- class any
- {
- public:
- any()
- : m_content(nullptr)
- {}
-
- //构造过程中,将传入参数复制给holder模板类
- template<typename ValueType>
- any(const ValueType &value)
- : m_content(new holder<ValueType>(value))
- {}
-
- any(const any &other)
- : m_content(other.m_content ? other.m_content->clone() : 0)
- {}
-
- ~any()
- {
- delete m_content;
- }
-
- any &swap(any &rhs)
- {
- std::swap(m_content, rhs.m_content);
- return *this;
- }
-
- template<typename ValueType>
- any &operator=(const ValueType &rhs)
- {
- any(rhs).swap(*this);
- return *this;
- }
-
- any &operator=(const any &rhs)
- {
- any(rhs).swap(*this);
- return *this;
- }
- public:
- bool empty() const
- {
- return !m_content;
- }
-
- const std::type_info &type() const
- {
- return m_content ? m_content->type() : typeid(void);
- }
- private:
- //一个非模板类的基类用于创建非模板类指针
- class placeholder
- {
- public:
- virtual ~placeholder()
- {}
- public:
- virtual const std::type_info &type() const = 0;
-
- virtual placeholder *clone() const = 0;
- };
-
- //继承placeholder类,并添加一个模板用于存储各种类型的参数
- template<typename ValueType>
- class holder : public placeholder
- {
- public:
- typedef ValueType value_type;
-
- holder(const ValueType &value)
- : m_held(value)
- {}
- public:
- virtual const std::type_info &type() const
- {
- return typeid(ValueType);
- }
-
- virtual placeholder *clone() const
- {
- return new holder(m_held);
- }
- public:
- ValueType m_held;
- };
- private:
- template<typename ValueType> friend ValueType *any_cast(any*);
-
- placeholder *m_content;
- };
-
- class bad_any_cast : public std::bad_cast
- {
- public:
- virtual const char *what() const throw()
- {
- return "bad_any_cast: "
- "failed conversion using any_cast";
- }
- };
-
- template<typename ValueType>
- ValueType *any_cast(any *operand)
- {
- return operand && operand->type() == typeid(ValueType)
- ? &static_cast<any::holder<ValueType>*>(operand->m_content)->m_held
- : 0;
- }
-
- template<typename ValueType>
- const ValueType *any_cast(const any *operand)
- {
- return any_cast<ValueType>(const_cast<any*>(operand));
- }
-
- template<typename ValueType>
- ValueType any_cast(const any &operand)
- {
- const ValueType *result = any_cast<ValueType>(&operand);
- return result ? *result : throw bad_any_cast();
- }
- #endif
我的参数包类parameters就是基于any类型实现的:
- class out_of_bound_of_parameters : public std::bad_cast
- {
- public:
- virtual const char *what() const throw()
- {
- return "parameters of the cross";
- }
- };
-
- class parameters
- :public std::vector<any>
- {
- public:
- parameters()
- {
- }
-
- /*
- 完成参数包的构造
- 调用示例:
- parameters objectname({1,std::string("1"),std::wstring(L"1")})
- 其中 "1" 和 L"1" 默认为字符数组类型,需要转化为非数组形式
- parameters *objectname = new parameters({std::function<void(void)>([](){...}),(char*)("1")})
- 其中[](){...}为函数类型,需要用函数指针或function模板指明函数结构;"1" 默认为字符数组类型,需要转化为非数组形式
- */
- parameters(const std::initializer_list<any> &args)
- {
- insert(begin(), args.begin(), args.end());
- }
-
- //在析构时清理stl容器,并释放对象
- ~parameters()
- {}
-
- /*
- 根据序号从参数包中把参数获取出来
- 其中_Type的类型,必须和参数传入时的类型完全一致,否则会抛出异常bad_any_cast
- 序号index不得超过参数包的参数,否则会抛出异常out_of_bound_of_parameters
- */
- template<class _Type>
- _Type get(const int &index)
- {
- return index < size() ?
- any_cast<_Type>(at(index)) :
- throw out_of_bound_of_parameters();
- }
-
- //往参数包中继续添加参数,添加的参数序号自动往后分配
- void add(const any &data)
- {
- push_back(std::move(data));
- }
-
- //根据序号将参数包中的某个参数移除,后面的参数序号自动向前补位
- bool remove(const const int &index)
- {
- if (index < size())
- {
- erase(begin() + index);
- return true;
- }
- return false;
- }
-
- //从一个参数包中拷贝数据
- void copy(const parameters &args)
- {
- assign(args.begin(), args.end());
- }
- };
都是很简单的代码,但parameters这个类在实际使用过程中十分方便,除了之前提到过的回调函数,其他通信过程以parameters传递参数也十分方便。
版权声明:本文为博主原创文章,未经博主允许不得转载。
https://blog.csdn.net/sjtxwangxin
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。