C ++中的分层数据

时间:2010-09-11 08:08:06

标签: c++ hierarchical-data

如何在新的动态语言中处理C ++中的数据,例如PHP中的数组非常简洁:

$arr = array(

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

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

"simple_data_again" => 198792,

);

我愿意接受所有建议。

5 个答案:

答案 0 :(得分:4)

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

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

答案 1 :(得分:4)

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

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

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

如果您需要动态输入和/或反思,请使用支持它们的语言,您将获得更好的服务。

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

大多数语言可以用于相同的目的,并不意味着在核心下以相同的方式处理事物。尝试通过语句将语言移植到另一个语句是令人沮丧的(在最好的时候)。

答案 2 :(得分:4)

如果您提前知道将会保留所有类型的值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<实现,提供了所有提供类型的类型。


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 ++的做事方法,并尝试将它们应用到您的特定问题中。


<强>参考文献:

答案 3 :(得分:2)

看看C ++中的'地图',有一篇很好的维基百科文章here

答案 4 :(得分:1)

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;

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