Json 类中主要定义:
- Json数据中的数据格式Type,包括Int, double, bool, String, Array, object
- Json的大量构造函数,包括1中的各个类型的构造,以及三个模板构造函数:
1)对于含有to_json方法对象的构造
2)对于像map,unordered_map相似的对象的构造
3)对于像set,list,vector对象的构造
4)对空指针类型构造的限制删除- Json是1中哪种类型的判别,以及获取当前Json的类型Type
- 声明获取Json中各种类型值的接口
- Json对象的序列化和解析
- Json对象之间的比较操作
- 最后的has_shape相当于确定json数据格式的正确性
- 数据成员为一个JsonValue的指针
其中主要的两个模板函数较难理解
/*
模板参数中第一个表示一个类型,第二个是对第一个类型的一个限制,
表示第一个类型中必须要一个to_json函数
*/
template<class T, class = decltype(&T::to_json)>
Json(const T &t): Json(t.to_json()){}
/*
像std::map std::unordered_map类似的数据结构
enable_if原型:
*** template< bool B, class T = void >
struct enable_if;
若 B 为 true ,则 std::enable_if 拥有等同于 T 的公开成员 typedef type;
若 B 为 false, 则std::enable_if为未定义。
*** template< class T, class... Args >
struct is_constructible;
T可以是对象类型也可以是引用类型,如果类型T能够使用Args作为参数进行构造,则is_constructible的名为value的常量成员值为ture, 否则为false
*** template<class T>
typename std::add_rvalue_reference<T>::type declval() noexcept;
declval是一个函数模板,返回指定T类型的一个右值引用
模板参数列表中,第二个参数主要是对T作限制,它要求T:
必须有key_type成员,且key_type类型的对象可用于构造string
必须有mapped_type成员,且mapped_type类型的对象可用于构造Json
另外,在最后一行构造object时,使用了t的begin和end成员,所以t必须具备这两个成员,否则编译失败。
最后的*::type = 0是给默认类型提供一个默认值【第二个参数不具名且提供了默认值】
*/
#define FIRSTVALUE std::is_constructible<std::string, decltype(std::declval<T>().begin()->first)>::value
#define SECONDVALUE std::is_constructible<Json, decltype(std::declval<T>().begin()->second)>::value
template<class T, typename std::enable_if<FIRSTVALUE && SECONDVALUE, int>::type = 0>
Json(const T &t):Json(object(t.begin(), t.end()));
/*
构造像vector,list, set这样的对象
原理同上
*优先级低于.
所以首先假设T是一个vector对象,std::declval<T>()返回一个vector对象的右值引用
.优先级高,所以先进行类似vector.begin()得到一个迭代器对象,随后*iterator表示vector中的值
最后decltype推导出类型
*/
#define BOOLISVARIABLE std::is_constructible<Json, decltype(*std::declval<T>().begin())>::value
template<class T, typename std::enable_if<BOOLISVARIABLE, int>::type = 0>
Json(const T &t):Json(array(t.begin(), t.end())){}