first of all i am a beginner to cpp. How can we define a map inside a map like
std:: map<std ::string,int> map_0={{"hello",1},{"a",3},{"b",5}}
std:: map<std ::string,int> map_1={{"hi",2},{"2",3},{"3",4}}
now i want to assign new element which can refer to my map_0 like
map_1["print"] = (int) & map_0;
(just wrote down i don't know correct expression to express here)
so that i can do some thing like $map_1["print"]=\%map_0;
in perl
答案 0 :(得分:2)
Key points: trying to naively port perl code to C++ may be quite difficult; the way datastructures work in the two langauges is quite different. You say you are a C++ beginner... this means you might not be the best person to do this sort of language translation. That said, here are some possibilities.
You can't trivially do this in a strongly statically typed language like C++. You could use something like std::variant
in C++17 to do this, by letting your map
elements be an int
or another map
, or maybe std::any
(also in C++17) so let the map contain anything at all (the closest to the perl behaviour you're likely to get). Neither of these types are entirely straightforward to use, compared to perl... you need to check what type was stored in the container, and use an appropriate accessor function or you'll get a compile error or runtime error, depending on circumstances. The docs should definitely be read!
Here's a std::variant
example. You can see that the nested type declarations can get pretty spammy pretty quickly if you want multiple levels of maps, so it might not be totally suitable for your needs.
std::map<std::string, std::variant<int, std::map<std::string, int>>> m;
m["foo"] = 1;
m["bar"] = std::map<std::string, int>{ {"baz", 2} };
m["bar"] = 3;
std::cout << std::get<int>(m["bar"]) << "\n";
You can use std::variant::index
to find out which one of the list of types is currently stored in the variant
, amongst other ways.
There are various libraries which offer a variant type that would work under older compilers and standard libraries, or you could even roll your own (though thius might not be worth it). There are also things called "tagged unions" which are very similar.
Here's a std::any
example. This has the advantage that you can multiple levels of nested map without needing huge typedefs.
std::map<std::string, std::any> m2;
m2["foo"] = 1;
m2["bar"] = std::map<std::string, int>{ { "baz", 2 } };
m2["bar"] = 3;
m2["qux"] = m;
std::cout << std::any_cast<int>(m2["bar"]) << "\n";
You can use std::any::type
to see which particular type the any
holds at a particular type, so you know which kind of any_cast
to use.
You'll need a newish compiler to use these features... I've used visual studio 2017 with /std:c++latest
and g++ 7.1 with -std=c++17
. These features may well be unavailable to you if you're using older compilers.