C++ 中的分层数据

发布于 2024-09-18 21:24:13 字数 268 浏览 9 评论 0原文

我如何像在较新的动态语言中一样处理 C++ 中的数据,例如 PHP 中的数组非常整洁:

$arr = array(

"somedata" => "Hello, yo, me being a simple string",

"somearray" => array(6 => 5, 13 => 9, "a" => 42),

"simple_data_again" => 198792,

);

我愿意接受所有建议。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

谷夏 2024-09-25 21:24:13

如果您提前知道map 将保存什么类型的值,那么请使用boost::variant。或者,使用 boost::any。使用 boost::any,您可以稍后将具有任何类型值的条目添加到地图中。


使用 boost::variant 的示例代码:

创建地图:

typedef boost::variant<std::string, std::map<int, int>, int> MyVariantType;
std::map<std::string, MyVariantType> hash;

添加条目:

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;

检索值:

std::string s = boost::get<std::string>(hash["somedata"]);
int i = boost::get<int>(hash["simple_data_again"]);

正如 @Matthieu M 在评论中指出的,映射的键类型可以是 boost::variant 。这是可能的,因为 boost::variant 提供了默认的 operator< 实现,提供了 all 中的类型。


使用 boost::any 的示例代码:

创建地图:

std::map<std::string, boost::any> hash;

添加条目:

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;

检索值:

std::string s = boost::any_cast<std::string>(hash["somedata"]);
int i = boost::any_cast<int>(hash["simple_data_again"]);

因此,在 boost::any 的帮助下获取值- 地图中的类型可以是动态的(某种程度上)。键类型仍然是静态的,我不知道如何使其动态。


忠告

C++ 是一种静态类型语言。像您帖子中这样在动态语言中经常使用的习惯用法与 C++ 语言不太适合。违背语言的本质会带来痛苦。

因此,我建议您不要尝试在 C++ 中模仿您最喜欢的动态语言中的习惯用法。相反,学习 C++ 的做事方法,并尝试将它们应用于您的特定问题。


参考文献:

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:

柠栀 2024-09-25 21:24:13

虽然我了解动态类型语言的吸引力,但它不太适合 C++。

C++ 是静态类型的,这意味着编译器知道变量的类型,因此可以安全地处理它。

有多种方法可以模拟动态类型(例如使用 Boost.Any),但真正的问题是为什么?

如果您需要动态类型和/或反射,那么使用支持它们的语言,您会得到更好的服务。

如果您需要/想要 C++,请学习如何使用 C++ 进行编程,而不是尝试逐字移植 PHP。

大多数语言都可以达到相同的目的,但这并不意味着事物在核心下以相同的方式处理。尝试将一种语言逐条语句移植到另一种语言(即使在最好的情况下)也是令人沮丧的。

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.

孤凫 2024-09-25 21:24:13

C++ 不提供对动态类型分层数据的内置支持,但您可以从较低级别的基元构建一个或使用第三方库,例如:

  1. std::mapboost::variantboost::any 作为值类型。
  2. boost::property_tree

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:

  1. std::map with boost::variant or boost::any as value type.
  2. boost::property_tree
鯉魚旗 2024-09-25 21:24:13

看看 C++ 中的“地图”,有一篇很好的维基百科文章 这里< /a>.

Have a look a 'map' in C++, there's a good Wikipedia article here.

缱绻入梦 2024-09-25 21:24:13

更准确地说,boost::variant 可以保存“类型联合”。这是一个如何定义与所请求的表达式类似的表达式的示例:

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;

您甚至可以定义此类结构的递归变体,其中包含 boost::variant< 的另一个 std::map /代码>。请注意,这与您可能想到的不同:boost::variant 是具有关联值的类型的类型安全联合。您可以使用它来实现动态语言的编译器,该编译器将允许根据您的要求进行构造。 c++ 本身不是动态的 - 一切都需要强类型。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文