[英]Store multiple types as values in C++ dictionary?
I want to write a C++ object that behaves almost equivalent to a Python dictionary.我想编写一个行为几乎等同于 Python 字典的 C++ 对象。 C++'s
std::map
and std::unordered_map
accommodate some of the functionalities that Python dictionaries already have, yet lack one of the most important capabilities, namely, being able to add arbitrary objects and types. C++ 的
std::map
和std::unordered_map
包含 Python 字典已有的一些功能,但缺少最重要的功能之一,即能够添加任意对象和类型。 Even if it isn't possible, how close can you get to achieving the capabilities of Python's dictionary?即使不可能,您离实现 Python 字典的功能还有多远?
A few previous questions ( here and here ) fail to handle the issue of adding multiple types to the dictionary.之前的一些问题( 此处和此处)无法处理向字典添加多种类型的问题。
For example, I want to be able to do something like this in C++:例如,我希望能够在 C++ 中做这样的事情:
my_dict = {'first': 1,
'second': "string",
'third': 3.5,
'fourth': my_object}
my_dict['fifth'] = list([1, 2, 3])
The best solutions that I can think would be like using void
pointers to data which get reinterpreted, or perhaps some kind of run-time polymorphism with some type restrictions?我能想到的最好的解决方案是使用指向被重新解释的数据的
void
指针,或者某种具有某些类型限制的运行时多态性?
The best solutions that I can think would be like using void pointers to data which get reinterpreted , or perhaps some kind of run-time polymorphism with some type restrictions?
我能想到的最佳解决方案是使用指向重新解释的数据的空指针,或者某种具有某些类型限制的运行时多态性?
Many void pointers and many reinterpretation of pointers in modern C++ should be a signal of a bad design, in my opinion.在我看来,现代 C++ 中的许多空指针和对指针的许多重新解释应该是一个糟糕设计的信号。 I believe that polymorphism would be a way to go.
我相信多态性将是一种方法。
Also, if you have a fixed number of types you want to use, consider using C++17's std::any or std::variant which is a more modern union
.此外,如果您想要使用固定数量的类型,请考虑使用 C++17 的std::any或std::variant ,这是一个更现代的
union
。
#include <iostream>
#include <map>
#include <string>
#include <variant>
typedef std::map<std::variant<int, std::string>, std::variant<int, std::string>> Dict;
int main(){
Dict d;
d["key"] = 1;
d[5] = "woah";
std::cout << std::get<int>(d["key"]) << std::endl; // prints 1
// edit: print all the keys in d
for(auto& k_v: d){
std::visit(
[](auto& value){std::cout << value << ' ';},
k_v.first // k_v.second to print all values in d
);
}
}
The above example might be useful in some use-cases.上面的示例在某些用例中可能很有用。
Also check out how json objects are implemented in any C++ json library.还要查看 json 对象是如何在任何 C++ json 库中实现的。 It might be helpful.
它可能会有所帮助。
Edit: I added an example of std::visit
that iterates over keys in our dictionary.编辑:我添加了一个
std::visit
示例,它遍历字典中的键。
I was looking for a similar solution for hard coding the parameters of my python
experiments into c++
.我正在寻找类似的解决方案,将我的
python
实验的参数硬编码到c++
。 I found the std'17 variant
module very useful.我发现
std'17 variant
模块非常有用。
#include <iostream>
#include <map>
#include <variant>
#include <vector>
#include <string>
int main(){
typedef std::map<std::variant<std::string, int>, std::variant<int, double, float, std::string>> Dict;
std::vector<Dict> params = {
{
{"label", "Labs"},
{"dir", "/media/sf_Data/"},
{"num_frames", 4},
{"scale_factor", 1.0},
{5, "my number five"},
}, // Dict 0
{
{"label", "Airplanes"},
{"dir", "/media/m_result/"},
{"num_frames", 5},
{"scale_factor", 0.5},
{5, "number five"},
} // Dict 1
};
int idx = 1;
std::string label = std::get<std::string>(params[idx]["label"]);
std::string folder = std::get<std::string>(params[idx]["dir"]);
int num_frames = std::get<int>(params[idx]["num_frames"]);
double scf = std::get<double>(params[idx]["scale_factor"]);
std::string nbstr = std::get<std::string>(params[idx][5]);
std::cout << label << std::endl;
std::cout << folder << std::endl;
std::cout << num_frames << std::endl;
std::cout << scf << std::endl;
std::cout << nbstr << std::endl;
return 0;
}
The result:结果:
Airplanes
/media/m_result/
5
0.5
number five
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.