无法连接输入字符串以检索 JSON 值...但可以对其进行硬编码
Can't concatenate input string for retreiving JSON value... but can hardcode it
我正在尝试遍历 JSON 中的对象列表以找到具有匹配 KVP 的对象(在 C++ 中使用 RapidJSON)。我已经设法使用硬编码指针检索值,但无法获得函数 GetValueByPointer(document, "PointerString")
来接受我正在构建的动态字符串。
JSON 看起来像这样:
{ "_id" : { "$oid" : "5d0985973f1c0000ee000000" },
"Location" : [ { "lat" : "39.4005", "lon" : "-106.106"} ],
"Weather" : [ { "timestamp" : "2019-06-05T00:00:00", ...}, { "timestamp" : "2019-06-05T01:00:00", ...}}
这个有效:
Document document;
document.Parse(json);
Value* a = GetValueByPointer(document, "/Weather/1/timestamp");
std::cout << a->GetString() << std::endl;
这行不通:
Value* a = GetValueByPointer(document, "/Weather/1/timestamp");
int i = 1;
std::string base = "/Weather/";
std::string tail = "/timestamp";
std::string PointerString;
std::string TSString = "";
while(TSString != "2019-06-05T09:00:00") {
PointerString=base;
PointerString.append(std::to_string(i));
PointerString.append(tail);
PointerString = "\"" + PointerString + "\"";
Value* timestamp = GetValueByPointer(document, PointerString);
TSString = timestamp->GetString();
std::cout << TSString << std::endl;
i++;
}
无论我尝试将 PointerString 转换成什么,我得到的错误是:
/usr/local/include/rapidjson/pointer.h:1156:30: note: template argument deduction/substitution failed:
MGOIO.cc:145:62: note: mismatched types ‘const CharType [N]’ and ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
Value* timestamp = GetValueByPointer(document, PointerString);
^
当我将 PointerString
输出到屏幕时,它看起来不错:
"/Weather/1/timestamp"
非常感谢任何帮助!
如果您查看 Pointer.h
,您会看到 GetValueByPointer()
的各种模板定义。
template <typename T>
typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
return pointer.Get(root, unresolvedTokenIndex);
}
template <typename T>
const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
return pointer.Get(root, unresolvedTokenIndex);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
}
template <typename T, typename CharType, size_t N>
const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
}
现在,您希望的是 std::string -> GenericPointer<...>
的隐式类型转换,这不会发生,因为 C++ 规则最多允许 1 个隐式类型转换。在这里,你需要 std::string -> const CharType(&source)[N] -> GenericPointer<...>
,这是一个太多的隐式转换。
我认为解决你的困境最简单的方法是编写你自己的这个函数的版本(你可能会调用它几次),当然要像其他函数一样模板化,并且需要 const std::string &
或 const std::basic_string<CharType>&
并明确地进行转换。
那个,再加上删除我在评论中提到的行应该有效。
我通过切换到 nlohmann JSON 解决了这个问题。由于 nlohmann 的指针是为接受字符串而构建的,因此非常简单。我在这里用 JSON 代替了我如何获得 JSON。
#include <iostream>
#include <string>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
json j = json::parse(JSON);
int i = 0;
int k;
std::string base = "/Weather/";
std::string tail = "/timestamp";
std::string PointerString;
std::string TSString = "";
while(TSString != "2019-06-05T09:00:00") {
PointerString=base;
PointerString.append(std::to_string(i));
PointerString.append(tail);
json::json_pointer p1(PointerString);
TSString = j.at(p1);
std::cout << TSString << std::endl;
std::cout << i << std::endl;
k=i;
i++;
}
我正在尝试遍历 JSON 中的对象列表以找到具有匹配 KVP 的对象(在 C++ 中使用 RapidJSON)。我已经设法使用硬编码指针检索值,但无法获得函数 GetValueByPointer(document, "PointerString")
来接受我正在构建的动态字符串。
JSON 看起来像这样:
{ "_id" : { "$oid" : "5d0985973f1c0000ee000000" },
"Location" : [ { "lat" : "39.4005", "lon" : "-106.106"} ],
"Weather" : [ { "timestamp" : "2019-06-05T00:00:00", ...}, { "timestamp" : "2019-06-05T01:00:00", ...}}
这个有效:
Document document;
document.Parse(json);
Value* a = GetValueByPointer(document, "/Weather/1/timestamp");
std::cout << a->GetString() << std::endl;
这行不通:
Value* a = GetValueByPointer(document, "/Weather/1/timestamp");
int i = 1;
std::string base = "/Weather/";
std::string tail = "/timestamp";
std::string PointerString;
std::string TSString = "";
while(TSString != "2019-06-05T09:00:00") {
PointerString=base;
PointerString.append(std::to_string(i));
PointerString.append(tail);
PointerString = "\"" + PointerString + "\"";
Value* timestamp = GetValueByPointer(document, PointerString);
TSString = timestamp->GetString();
std::cout << TSString << std::endl;
i++;
}
无论我尝试将 PointerString 转换成什么,我得到的错误是:
/usr/local/include/rapidjson/pointer.h:1156:30: note: template argument deduction/substitution failed:
MGOIO.cc:145:62: note: mismatched types ‘const CharType [N]’ and ‘std::__cxx11::string {aka std::__cxx11::basic_string<char>}’
Value* timestamp = GetValueByPointer(document, PointerString);
^
当我将 PointerString
输出到屏幕时,它看起来不错:
"/Weather/1/timestamp"
非常感谢任何帮助!
如果您查看 Pointer.h
,您会看到 GetValueByPointer()
的各种模板定义。
template <typename T>
typename T::ValueType* GetValueByPointer(T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
return pointer.Get(root, unresolvedTokenIndex);
}
template <typename T>
const typename T::ValueType* GetValueByPointer(const T& root, const GenericPointer<typename T::ValueType>& pointer, size_t* unresolvedTokenIndex = 0) {
return pointer.Get(root, unresolvedTokenIndex);
}
template <typename T, typename CharType, size_t N>
typename T::ValueType* GetValueByPointer(T& root, const CharType (&source)[N], size_t* unresolvedTokenIndex = 0) {
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
}
template <typename T, typename CharType, size_t N>
const typename T::ValueType* GetValueByPointer(const T& root, const CharType(&source)[N], size_t* unresolvedTokenIndex = 0) {
return GenericPointer<typename T::ValueType>(source, N - 1).Get(root, unresolvedTokenIndex);
}
现在,您希望的是 std::string -> GenericPointer<...>
的隐式类型转换,这不会发生,因为 C++ 规则最多允许 1 个隐式类型转换。在这里,你需要 std::string -> const CharType(&source)[N] -> GenericPointer<...>
,这是一个太多的隐式转换。
我认为解决你的困境最简单的方法是编写你自己的这个函数的版本(你可能会调用它几次),当然要像其他函数一样模板化,并且需要 const std::string &
或 const std::basic_string<CharType>&
并明确地进行转换。
那个,再加上删除我在评论中提到的行应该有效。
我通过切换到 nlohmann JSON 解决了这个问题。由于 nlohmann 的指针是为接受字符串而构建的,因此非常简单。我在这里用 JSON 代替了我如何获得 JSON。
#include <iostream>
#include <string>
#include <fstream>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
json j = json::parse(JSON);
int i = 0;
int k;
std::string base = "/Weather/";
std::string tail = "/timestamp";
std::string PointerString;
std::string TSString = "";
while(TSString != "2019-06-05T09:00:00") {
PointerString=base;
PointerString.append(std::to_string(i));
PointerString.append(tail);
json::json_pointer p1(PointerString);
TSString = j.at(p1);
std::cout << TSString << std::endl;
std::cout << i << std::endl;
k=i;
i++;
}