我用 C 構建了一個簡單的 JSON 編碼器/解碼器(我知道有很多優秀的解決方案可以解決這個問題;我正在學習這門語言,這對我自己來說只是一個挑戰,我不會假裝我的解決方案有什么好處)。
最初,我有以下兩個operator []多載:
json& operator[](const std::string& key) {
assert_type_valid(/* "object" type */);
return (*object_data_)[key];
}
json& operator[](size_t index) {
assert_type_valid(/* "array" type */);
return (*array_data_)[index];
}
...
std::unique_ptr<std::unordered_map<std::string, json>> object_data_;
std::unique_ptr<std::vector<json>> array_data_;
這很好用!我可以做一些類似my_json["someKey"]["someOtherKey"][4]["thirdKey"]訪問嵌套值的事情。
但是,因為我的專案使用了一堆同時使用char/std::string和wchar_t/的 Windows API,所以std::wstring我想同時創建json和wjson型別,所以我將現有的json類和決議器變成了basic_json<CharType, StringType>.
現在,相同的代碼如下所示:
// Using C for CharType and S for StringType for brevity here...
basic_json<C, S>& operator[](const S& key) {
assert_type_valid(/* "object" type */);
return (*object_data_)[key];
}
basic_json<C, S>& operator[](size_t index) {
assert_type_valid(/* "array" type */);
return (*array_data_)[index];
}
...
std::unique_ptr<std::unordered_map<S, basic_json<C, S>>> object_data_;
std::unique_ptr<std::vector<basic_json<C, S>>> array_data_;
現在嘗試使用任何一種都會operator []導致此錯誤:
error C2666: 'basic_json<char,std::string>::operator []': 2 overloads have similar conversions
could be ...::operator [](size_t)
or ...::operator [](const S &)
or built-in C operator[(__int64, const char [8])
我嘗試添加第三個operator [](const C* key)多載,但這并沒有什么不同。
我的實際問題:為什么模板會導致這種情況?
我的印象是模板型別是在編譯時確定的,所以大概編譯器應該理解什么C和S是,并且能夠知道我沒有在size_t我做的時候傳遞my_json["someKey"]。
另外,我覺得模板已經把曾經漂亮的代碼變成了一個巨大的混亂。在這種情況下是否值得簡單地復制一堆代碼?就像有第二個決議器可以明確地與wchar_tand一起作業std::wstring?
uj5u.com熱心網友回復:
“為什么模板會導致這種情況?” 因為類模板成員只在必要時被實體化。
線索似乎在您未提及的 operator[] 中:
built-in C operator[(__int64, const char [8]).
也就是說,編譯器認為5["someKey"]. 等等,什么?是的,在 C 中這是有效的。"someKey"[5]為了與 C 兼容,它與 , 相同。
現在這有什么關系?你basic_json<C, S>有一個隱式轉換int和std::string一個隱式轉換 from const char [8],所以這兩個多載是相等的。
修復:洗掉隱式轉換為int.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/519912.html
標籤:C json模板
下一篇:C 98中的SFINAE
