Reputation: 854
How can I handle data in C++ like in newer dynamic languages, for example the arrays in PHP are quite neat:
$arr = array(
"somedata" => "Hello, yo, me being a simple string",
"somearray" => array(6 => 5, 13 => 9, "a" => 42),
"simple_data_again" => 198792,
);
I am open to all suggestions.
Upvotes: 3
Views: 4250
Reputation: 84922
C++ doesn't provide a built-in support for dynamically typed hierarchical data, but you can build one from lower-level primitives or use a third-party library, for example:
std::map
with boost::variant
or boost::any
as value type.boost::property_tree
Upvotes: 4
Reputation: 92096
If you know in advance what all kinds of values map
is going to hold, then use boost::variant
. Or else, use boost::any
. With boost::any
, you could later add entries with any type of value to the map.
Example code with boost::variant
:
Creating a map:
typedef boost::variant<std::string, std::map<int, int>, int> MyVariantType;
std::map<std::string, MyVariantType> hash;
Adding entries:
hash["somedata"] = "Hello, yo, me being a simple string";
std::map<int, int> temp;
temp[6] = 5;
temp[13] = 9;
hash["somearray"] = temp;
hash["simple_data_again"] = 198792;
Retrieving values:
std::string s = boost::get<std::string>(hash["somedata"]);
int i = boost::get<int>(hash["simple_data_again"]);
As pointed out by @Matthieu M in the comments, the key-type of the map can be a boost::variant
. This becomes possible because boost::variant
provides a default operator<
implementation providing the types within all provide it.
Example code with boost::any
:
Creating a map:
std::map<std::string, boost::any> hash;
Adding entries:
hash["somedata"] = "Hello, yo, me being a simple string";
std::map<int, int> temp;
temp[6] = 5;
temp[13] = 9;
hash["somearray"] = temp;
hash["simple_data_again"] = 198792;
Retrieving values:
std::string s = boost::any_cast<std::string>(hash["somedata"]);
int i = boost::any_cast<int>(hash["simple_data_again"]);
Thus, with help of boost::any
the value-type in your map can be dynamic (sort of). The key-type is still static, and I don't know of any way how to make it dynamic.
A word of advice:
C++ is a statically typed language. The idioms like the one in your post which are used quite often in dynamic language don't fit well with the C++ language. Going against the grain of a language is a recipe for pain.
Therefore I'd advise you not to try to emulate the idioms from your favorite dynamic languages in C++. Instead learn the C++ ways to do things, and try to apply them to your specific problem.
References:
Upvotes: 4
Reputation: 300179
While I understand the appeal of dynamically typed languages, it doesn't fit well with C++.
C++ is statically typed, which means that the compiler knows which type a variable is going to be and therefore can process it safely.
There are ways to emulate dynamic typing (use of Boost.Any for example), but the real question is WHY ?
If you need dynamic typing and/or reflection, then use a language that support them, you'll be better served.
If you need/want C++, learn how to program in C++ instead of trying to port PHP verbatim.
Most languages can serve the same purpose, it doesn't mean things are processed in the same manner under the core. It's frustrating (at the best of times) to try to port a language to another statement by statement.
Upvotes: 4
Reputation: 4381
boost::variant
can hold a "union of types", to be more exact. This is an example of how you could define an expression similar to the requested one:
std::map
<
std::string,
boost::variant
<
std::string,
std::array<int, 4>,
int
>
> my_variant_array;
my_variant_array["somedata"] = "Hello, yo, me being a simple string";
my_variant_array["somearray"] = {
1, 2, 3, 4
};
my_variant_array["simple_data_again"] = 198792;
You could even define a recursive variation of such a structure containing another std::map
of boost::variant
. Please be aware, that this is something different from what you probably have in mind: boost::variant
is a type safe union of types with associated values. You could use it, to implement a compiler for a dynamic language which would allow constructs as you requested. c++ per se is not dynamic - everything needs to be strongly typed.
Upvotes: 1