我想创建一个像 nlohaman::json 的结构。 nlohaman;:json 结构的神奇之处在于它几乎可以容纳任何类型的数据,它的美妙之处在于你不需要调用任何愚蠢的函数来获取你的值。
这就是我的意思,
#include <iostream>
#include <string>
#include "nlohmann/json.hpp"
using namespace std;
int main(int argc, char *argv[])
{
nlohmann::json obj;
obj["string"] = "key";
cout<<obj["j"]<<"\n";
obj["hobbies"] = {"Reading", "Gaming", "Traveling"};
for (auto &it: obj["hobbies"])
{
cout<<it<<"\n";
}
return 0;
}
如果您观察到此结构的三个优点是。
std::get<std::string>(obj["string"])
从变体(或任何类型的值)中获取字符串值。obj["key"] = structName("value");
我正在尝试从一周开始创建一个这样的结构。 我尝试用联合、变体、结构创建这种结构,但没有一个是这样的。
看看我的一些实现。
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <vector>
#include <variant>
using namespace std;
// This one directly stores values
union val2 {
string s;
vector<string> v;
val2(const string &c) : s(c) {}
val2(const char *c) : s(c) {}
val2(const initializer_list<string> & z): v(z){}
~val2(){}
};
//This one stores pointer approach
union val {
string *v;
vector<string> *g;
val(const string &c) : v(new string(c)) {}
val(const char *c) : v(new string(c)) {}
val(const initializer_list<string> & z): g(new vector<string>(z)){}
val(const vector<string> & d) : g(new vector<string>(d)){}
val(const val &other)
{
if (other.v != nullptr)
{
v = new string(*other.v);
}
else if (other.g != nullptr)
{
g = new vector<string>(*other.g);
}
}
~val() {}
};
int main(int argc, char *argv[]
{
vector<val> v = {
"gh",
"u",
{"f", "d"}
};
vector<val2> n=
{
"g",
"h",
{"6"}
};
cout << *v[0].v << "\n";
cout<<n[2].v[0]<<"\n";
return 0;
}
如您所见,要获取字符串,我需要使用并集的 .s,向量的 .v。我在变体中实现了相同的结构,但我们再次需要使用
std::get<std::string>
来获取字符串,同样对于向量,我们需要使用 std::get<vector<std::string>(obj["v"])
。
告诉我其中哪一篇对您来说更具可读性。
//One with variant approach
std::vector<std::string> v = std::get<std::vector<std::string>>(obj["v"]);
//One with nlohaman json approach
std::vector<std::string> v = obj["v"];
我猜你更喜欢第二种方法。
我想创建类似的结构,所以如果你们中有人知道如何做到这一点,请回答这个问题。 预先感谢您的回答。
obj["v"];
正在调用一个“愚蠢的函数”。它称为operator[]
。如果您想要的话,您也可以超载operator[]
。
std::any
并将转换隐藏在模板化转换运算符中:
#include <any>
struct my_any {
std::any value;
template <typename T> my_any& operator=(const T& t) { value = t; return *this;}
template <typename T> operator T() {
return std::any_cast<T>(value);
}
};
int main() {
//std::any x = 42;
//int y = x; // Error, needs a cast
my_any foo;
foo = 42;
int x = foo; // OK uses the template conversion operator
}
这只是最基本的说明基础知识的骨架。仍然缺少适当的构造函数等。