2017-03-02 148 views
1
struct student { 
    string name; 
    int age; 
}; 

int main() { 
    student a1; 

    cout << a1[0] << endl; //Access the first variable of the struct 
    cout << a2[1] << endl; //Access the first variable of the struct 
} 

我怎样才能使用索引而不是使用“a1.name”从C++结构中访问和检索值?如何使用索引访问C++结构属性值?

+4

你不能。你为什么想做这个?如果你想要一个数组,使用一个数组。看起来像[XY问题](http://xyproblem.info/)。 –

+0

你不能在C++中做到这一点 – Sean

+0

如果语言允许......想象一下,如果你决定改变“学生”中成员的顺序,那么它会在你的程序中造成破坏。此外,这将是一个噩梦维持。你不能查找'a1 [0]'是否是名字或年龄,而不查找'struct'的定义。 –

回答

0

你不能。

直到在C++中引入反射,应该(我希望)是C++ 20中的情况。

Some projects介绍用名称增强的元组,但它仍然不是真正的结构。

1

如何使用索引访问C++结构属性值?

你不行。 C++语言没有这个功能。这可以用支持(静态)反射的语言来实现。

您可以选择使用std::tuple代替,该代码允许索引成员访问,但由于您无法命名成员,因此可读性下降。

3

你不能。至少不是以你想要做的直接方式,而不是部分地重新定义结构是什么。我将我的答案分成两个部分的第一个解释可能的方式得到至少接近你想要什么,第二个解释,你真正应该做的:

获取下来,脏

有两种方式(即我目前能拿出)这可能会给你一些思考:

  • 使用包装类 - 而C++确实增加了结构的灵活性,它并不会改变他们的目的简单的异构数据容器。但是,它确实允许操作员超载,包括[]操作员。因此,如果您创建一个包含结构作为其成员的类(即它包裹结构),则可以使用[]公开结构的数据。这尽可能接近你想要做的事情。但是它确实会破坏使用结构体的全部目的,因为你可以用简单的非结实类成员来完成这个工作,但是我实际上在很久以前就已经看到了,当时我正在浏览一个C++库,为了提供更现代的功能而不需要完全重写C代码。
  • 使用偏移量指针 - 使用索引通常表明底层容器在涉及其包含的数据块时具有一致性。问题是一个结构不一定遵守这个,因为它可以包含(就像你的情况一样)多种类型的数据。如果您可以牺牲结构的异质性并坚持使用单一数据类型(例如一个或多个双精度),则可以安全地使用(直到必须始终记住结构具有的成员数量)指针以及访问其成员的增加/减少的偏移量。就像创建标准引用(又名指针)时的任何类型的数据一样,该引用指向该数据使用的内存开始地址。使用指针来遍历数组是很常见的做法,它的工作方式就像这样 - 创建一个对结构的引用,并添加+1,+2,...(与结构体中的许多成员一样)。这使得事情过于复杂,并且容易出错。如前所述,它还需要在结构中使用相同类型的数据。

替代...

从你给的信息,我认为你正在寻找一个完全不同类型的数据 - 一本字典,地图或列表包含某种自定义的通用数据容器可以容纳任何类型的数据,但也可以存储该数据的类型,以便将其重新设置为原始状态。许多库提供这样的容器,例如Qt的QVariant(核心模块的一部分),boost有你的标准C++(自C++ 11以后)提供的boost::variantstd::tuple(或更好的命名元组),等等。我可以更详细地谈论Qt,因为我有更多的经验。它提供了QVariantListtypedefQList<QVariant>),它允许建立索引。当然,所有这些都需要你1)放弃你的结构,2)使用一些更高级的容器,这些容器可能会或可能不会在你正在做的任何事情上带来巨大的缺点,包括许可问题,内存开销,较大的二进制文件,处理大量的额外的库文件等。

+0

如何命名元组?不如反思,但接近目标,没有任何开销(编译时除外) –

+0

坦率地说,我从来没有使用过命名的元组。从网上的简短研究看来,这些是标准元组的更好的版本。所以是的,这应该是一个很好的解决方案。将编辑我的文章(我提到了元组,但现在也会添加指定版本)。谢谢! – rbaleksandar