最近在使用nlohmann的json,发现有些地方不是特别好用,因此就想本身修改一下(目的是为了增长相似jsoncpp中能够//增长注释的功能),在看源码的时候看到了一个迷惑的地方,就是解析jsonmysql
JSON_HEDLEY_WARN_UNUSED_RESULT static basic_json parse(detail::input_adapter&& i, const parser_callback_t cb = nullptr, const bool allow_exceptions = true) { basic_json result; parser(i, cb, allow_exceptions).parse(true, result); return result; }
第一个参数我传入的是一个istream,可是这里接收的是一个类。c++
调试的时候发现,先建立了一个input_adapater类sql
class input_adapter { public: // native support JSON_HEDLEY_NON_NULL(2) input_adapter(std::FILE* file) : ia(std::make_shared<file_input_adapter>(file)) {} /// input adapter for input stream input_adapter(std::istream& i) : ia(std::make_shared<input_stream_adapter>(i)) {} /// input adapter for input stream input_adapter(std::istream&& i) : ia(std::make_shared<input_stream_adapter>(i)) {} input_adapter(const std::wstring& ws) : ia(std::make_shared<wide_string_input_adapter<std::wstring>>(ws)) {} input_adapter(const std::u16string& ws) : ia(std::make_shared<wide_string_input_adapter<std::u16string>>(ws)) {} input_adapter(const std::u32string& ws) : ia(std::make_shared<wide_string_input_adapter<std::u32string>>(ws)) {} /// input adapter for buffer template<typename CharT, typename std::enable_if< std::is_pointer<CharT>::value and std::is_integral<typename std::remove_pointer<CharT>::type>::value and sizeof(typename std::remove_pointer<CharT>::type) == 1, int>::type = 0> input_adapter(CharT b, std::size_t l) : ia(std::make_shared<input_buffer_adapter>(reinterpret_cast<const char*>(b), l)) {}
在这里找到了istream,一个构造函数。json
当时比较懵,还有这种使用方法?用c++这么久没有发现哪里有明确指出这种使用方法。潜意思中觉着多是隐式转换。ide
本身写了几个测试程序发现,确实是这样,类若是有一个对应类型的构造函数,是能够默认转换的。函数
后来查资料,忽然想起来,常常用的string不就是这样用吗?测试
string str = "test";
咱们最经常使用的一种方法,这里就是调用了string里面const char*为参数的构造函数。能够调试查看xstring里面的这个函数spa
basic_string(_In_z_ const _Elem * const _Ptr) : _Mybase() { // construct from [_Ptr, <null>) _Tidy_init(); assign(_Ptr); }
参考 https://en.cppreference.com/w/cpp/language/converting_constructor https://zh.cppreference.com/w/cpp/language/converting_constructor调试
一个类的构造函数,若是没有声明explicit,而且传入的肯定参数只有一个(这里的意思就是,不必定这个构造函数就一个参数,能够多个参数,可是其余参数都是有默认值的),那么这个就是转换构造函数。code
做用就是把一个类型隐式的转换成类。
参考 https://zh.cppreference.com/w/cpp/language/explicit
与隐式转换对应出现的就是explicit关键字,既然提供了隐式转换,那么确定也有禁止隐式转换的方法。explicit关键字就是声明在构造函数前,明确指定,不容许隐式转换构造,必须是明确的
参考 https://en.cppreference.com/w/cpp/language/cast_operator
实际上上面的隐式转换属于这个范畴,就是用户自定义的转换。容许隐式和显式的转换类与一个其余类型。
使用方法,就是operator加上要转换的类型,加上函数的括号,不能加参数,函数内部返回这个值。
operator conversion-type-id
operator 类型 ()
{
return 类型;
}
class C1 { public: operator int() { return 1234; } }; int i1 = C1;
mysql connector中的sqlstring
class SQLString { std::string realStr; ~SQLString() {} SQLString() {} operator const std::string &() const { return realStr; } }
SQLString a = "aaa"; string b = a;
就是在上面这种赋值的时候,会调用到这个函数,帮忙转换成另一种类型,最好先后加const,防止改变内容