【问题标题】:Return pointer to any field in class/structure in C/C++返回指向 C/C++ 中类/结构中的任何字段的指针
【发布时间】:2016-05-22 09:14:45
【问题描述】:

我有一个结构,其中包含许多不同类型的字段:

struct team_stats{
    char team_name[ TEAM_NAME_LEN ]; // Name of NFL team
    int games; // Number of games played in the season
    float pts_per_game; // Points per game
    ...
} 

我创建了返回指向结构中任何字段的指针的方法 它看起来像:

template <class T>
T* getField (int fieldNum, team_stats &team) {
    if(fieldNum==0) return &team.team_name;
    if(fieldNum==1) return &team.games;
    if(fieldNum==2) return &team.pts_per_game;
    ...
}

例如我想读一些字段:

template <class T>
void readTeam(team_stats &team) {
    for (int i = 0; i < NO_FIELDS; i++) 
        cin >> *getField<T>(i,team);

出现问题:

由于我有一个模板,我需要在调用方法时传递一些类型 - getField(i, team)。但是我有不同类型的字段,编译器会说类似 " 的消息无法将 type of field games 转换为 some type"

统一更新: 但是对于外部函数我需要指定类型T,如何使其动态化?

UPD_2: 我找到了很好的解决方案!我在下面回答了我的问题!

【问题讨论】:

  • 你需要cin &gt;&gt; getField&lt;T&gt;(i,team);
  • 它有帮助,但它在外部函数中导致了同样的错误(for (int j = 0; j &lt; NO_TEAMS; j++) readTeam(arrayOfStats[i].teams[j]))。是否可以使用这种方法读取此结构的字段?问题是我需要动态识别字段的类型。
  • 您必须调用它来提供模板参数的类型。像readTeam&lt;int&gt;(team); 这样的东西。一般来说,你在那里尝试做的事情是行不通的。
  • 是的!我明白为什么这是不可能的)要取消引用指针,我们应该确切地知道这个指针的类型是什么。谢谢
  • 还有一个错误!当我传递类型 时,会导致某些字段无法转换的错误(但该字段永远无法访问)。

标签: c++ templates pointers types


【解决方案1】:

所以我希望自己回答这个问题:

对于每种类型,让我们创建和 重载 getField 方法,其中 第一个参数是字段编号,第二个 - 考虑的类 第三个是指向考虑字段的结果指针,通过引用传递, 看起来像:

void getField(int fieldNum, team_stats &team, int *& res) {
    if(fieldNum==1) res = &team.games;
    if(fieldNum==3) res = &team.total_points;
    if(fieldNum==4) res = &team.scrimmage_plays;
    ....
}
void getField(int fieldNum, team_stats &team, float *& res) {
    if(fieldNum==2) res = &team.pts_per_game;
    if(fieldNum==5) res = &team.yds_per_game;
    ....
}

void getField(int fieldNum, team_stats &team, char *& res) {
    if (fieldNum == 0) res = team.team_name;
    ....
}

所以现在阅读看起来像:

void readTeam(team_stats &team) {
    for (int i = 0; i < NO_FIELDS; i++) {
        if (isCharField(i)) {
            char * field;
            getField(i, team, field);
            readStringField(field);
        }
        if (isFloatField(i)) {
            float * field;
            getField(i, team, field);
            cin >> *field;
        }
        if (isIntField(i)) {
            int * field;
            getField(i, team, field);
            cin >> *field;
        }
    }

【讨论】:

  • 另外,我想说你应该把 if 语句的所有主体分解成它们自己的方法。
  • 什么意思?我不明白 =(
  • 你做这样的事情:isXXXField(i) { ... } 然后做一堆操作。如果这些操作包含在另一个方法中,它将看起来像 isXXXField(i) { doXXXStuff(i,team,field); } 并且变得更具可读性。接下来,它将帮助您发现您实际上可以如何使用模板化函数来做到这一点
  • 我正在寻找答案以向您展示我的意思。
  • 是的,这绝对是个好建议。谢谢。而且,您认为我应该将函数作为参数传递给 doStuff() 吗?因为对于某些领域,我需要具体阅读。
猜你喜欢
  • 2022-06-15
  • 2014-09-09
  • 1970-01-01
  • 1970-01-01
  • 2021-01-12
  • 2021-04-01
  • 2021-07-14
  • 1970-01-01
  • 2016-08-25
相关资源
最近更新 更多