最近在使用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,防止改變內容