[英]How to access C++ struct property value using index?
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
}
How could I access and retrieve value from the C++ struct using index instead of using "a1.name" ??如何使用索引而不是使用“a1.name”从 C++ 结构访问和检索值?
You can't.你不能。 At least not in the direct manner you want to do it and without partially redefining what a structure is.
至少不是以你想要的直接方式去做,也没有部分重新定义结构是什么。 I will split my answer into two parts the first one explaining possible ways to get at least close to what you want and the second one explaining what you actually should do:
我将把我的答案分成两部分,第一部分解释至少接近你想要的东西的可能方法,第二部分解释你实际应该做什么:
Getting down and dirty下来和肮脏
There are two ways (that I can currently come up with) that might give you something to think about:有两种方法(我目前可以想出)可能会让您有所思考:
[]
operator.[]
运算符。 So if you create a class that contains the structure as its member (that is it wraps around the structure), you can expose the structure's data using []
.[]
公开结构的数据。 This comes as close to what you want to do as possible. The alternatives ...替代品...
From what you have given as information I think you are looking for a completely different type of data - a dictionary, map or a list that contains some sort of custom generic data container that can hold any type of data but also stores that data's type in order to allow recasting it to its original state.根据您提供的信息,我认为您正在寻找一种完全不同类型的数据 - 字典、地图或列表,其中包含某种自定义通用数据容器,可以保存任何类型的数据,但也可以存储该数据的类型以允许将其重铸到其原始状态。 Many libraries provide such containers for example Qt has the
QVariant
(part of the core module), boost
has the boost::variant
, std::tuple
(or even better - named tuples) provided with your standard C++ (since C++11) and so on.许多库都提供了这样的容器,例如 Qt 有
QVariant
(核心模块的一部分), boost
有boost::variant
、 std::tuple
(甚至更好的命名元组)与标准 C++(自 C++11 起) ) 等等。 I can speak about Qt in greater detail since I have more experience with it.我可以更详细地谈论 Qt,因为我对它有更多的经验。 It offers the
QVariantList
(a typedef
for QList<QVariant>
) which allows indexing.它提供了允许索引的
QVariantList
( QList<QVariant>
的typedef
)。 Of course all this requires you to 1)abandon your structure-thing and 2)use some more advanced containers that may or may not introduce huge drawbacks on whatever you are working on including licensing issues, memory overhead, larger binaries, handling a lot of extra library files etc.当然,所有这些都要求您 1) 放弃您的结构和 2) 使用一些更高级的容器,这些容器可能会或可能不会对您正在处理的任何事情带来巨大的缺点,包括许可问题、内存开销、更大的二进制文件、处理大量额外的库文件等
How to access C++ struct property value using index?
如何使用索引访问 C++ struct 属性值?
You can not.你不能。 C++ language has no feature that would allow this.
C++ 语言没有允许这样做的功能。 This could be possible in a language that supports (static) reflection.
这在支持(静态)反射的语言中是可能的。
You could choose to use a std::tuple
instead, which does allow indexed member access, but that's a step down in readability since you don't get to name the members.您可以选择使用
std::tuple
代替,它允许索引成员访问,但由于您无法命名成员,因此可读性下降。
One way to do this is by creating a tuple from the member variables and using std::tie
to get at the member by index.一种方法是从成员变量创建一个元组并使用
std::tie
通过索引获取成员。 The index would have to be known at compile time however.但是,必须在编译时知道索引。 You could wrap this inside a member function of your struct:
您可以将其包装在结构的成员函数中:
#include <tuple>
#include <iostream>
struct student {
std::string name;
int age;
template<size_t I>
auto& get() {
return std::get<I>(std::tie(name, age));
}
};
int main() {
student boy{ "Paul", 12 };
std::cout << "Name: " << boy.get<0>() << " Age: " << boy.get<1>() << std::endl;
//Change members
boy.get<0>() = "John";
boy.get<1>() = 14;
std::cout << "Name: " << boy.get<0>() << " Age: " << boy.get<1>() << std::endl;
}
(Requires at least C++14) (至少需要 C++14)
In C++11, since it doesn't have automatic return type deduction unless specified, you could use std::tuple_element
to specify the return type instead:在 C++11 中,除非指定,否则它没有自动返回类型推导,因此您可以使用
std::tuple_element
来指定返回类型:
#include <tuple>
#include <iostream>
struct student {
std::string name;
int age;
template<size_t I>
using T = typename std::tuple_element<I, std::tuple<std::string, int>>::type;
template<size_t I>
T<I>& get()
{
return std::get<I>(std::tie(name, age));
}
};
int main() {
student boy{ "Paul", 12 };
std::cout << "Name: " << boy.get<0>() << " Age: " << boy.get<1>() << std::endl;
//Change members
boy.get<0>() = "John";
boy.get<1>() = 14;
std::cout << "Name: " << boy.get<0>() << " Age: " << boy.get<1>() << std::endl;
}
You cannot.你不能。
Not until reflection has been introduced in C++, which should (I hope) be the case in C++20.直到在 C++ 中引入了反射,在 C++20 中(我希望)应该是这种情况。
Some projects introduce tuples enhanced with names, but it still not real structs.一些项目引入了用名称增强的元组,但它仍然不是真正的结构。
I tried to stay as close to your example as possible but I did have to convert the age from int to string.我试图尽可能接近您的示例,但我确实必须将年龄从 int 转换为 string。 This works and I have found it useful in one application.
这有效,我发现它在一个应用程序中很有用。
struct student
{
std::string name, age;
std::string *elemtnPtr[10];
student()
{
int i=0;
elemtnPtr[i++] = &name;
elemtnPtr[i++] = &age;
}
};
void demo()
{
student a1;
a1.name = "This Works";
a1.age = "99";
std::cout << *a1.elemtnPtr[0] << std::endl;
std::cout << *a1.elemtnPtr[1] << std::endl;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.