使用循环填充结构

时间:2019-03-22 16:57:05

标签: c++

我有一个C ++结构

struct Line {
  int date;
  int time;
  float open;
  float high;
  float low;
  float close;
  float sd;
  float long_mo;
  float short_mo;
};

8个字段。 我想使用循环填充它。

int fields_count=1;
while (fields_count<=8) {
  // get digit from outer sourse. I dont need help here.
  // First iteration puts to 1 field, Second iteration puts to 2 field and so on up to last field of struct 
  fields_count++;
}

3 个答案:

答案 0 :(得分:2)

类似这样的东西:

#include<stddef.h>

struct Line {
  int date;
  int time;
  float open;
  float high;
  float low;
  float close;
  float sd;
  float long_mo;
  float short_mo;
};

char types [] = "iifffffff";
int offsets [] = {
  offsetof (Line, date),
  offsetof (Line, time),
  offsetof (Line, open),
  offsetof (Line, high),
  offsetof (Line, low),
  offsetof (Line, close),
  offsetof (Line, sd),
  offsetof (Line, long_mo),
  offsetof (Line, short_mo)
}

Line line;

for (int i = 0; i < 9; i++) {
  char *field_ptr = ((char*)&line) + offsets [i];

  if (types [i] == 'i')
    *(int*)field_ptr = readInt ();
  else if (types [i] == 'f')
    *(float*)field_ptr = readFloat ();
}

答案 1 :(得分:1)

在C ++ 20中,您可以使用expansion statements对集合进行迭代:

auto my_line = Line{};
auto fields_count = std::size_t{0};
for...(auto& member : my_line) {
    member = get_digit(fields_count++);
}

您甚至可以获取要迭代的成员的类型:

auto my_line = Line{};
auto fields_count = std::size_t{0};
for...(auto& member : my_line) {
    using type = std::remove_cvref_t<decltype(member)>;
    member = get_digit<type>(fields_count++);
}

答案 2 :(得分:0)

可悲的是,C ++中没有任何反映,因此没有一种执行所需操作的好方法。

使用现代C ++,您可以执行以下操作:

#include <cstddef>
#include <iostream>
#include <tuple>
#include <utility>

struct Line
{
    int date;
    int time;
    float open;
    float high;
    float low;
    float close;
    float sd;
    float long_mo;
    float short_mo;
};

template <typename ...P, std::size_t ...I, typename F>
void for_each_tuple_elem_low(std::tuple<P...> t, std::index_sequence<I...>, F &&func)
{
    (void(func(std::get<I>(t))) , ...);
}

template <typename ...P, typename F> void for_each_tuple_elem(std::tuple<P...> t, F &&func)
{
    for_each_tuple_elem_low(t, std::make_index_sequence<sizeof...(P)>{}, func);
}

int main()
{
    Line obj;
    auto &[x1,x2,x3,x4,x5,x6,x7,x8,x9] = obj;
    auto tuple = std::tie(x1,x2,x3,x4,x5,x6,x7,x8,x9);

    int i = 0;
    for_each_tuple_elem(tuple, [&](auto &ref)
    {
        ref = i++;
    });
}

在这里,样板简化为两次键入结构化绑定的名称:x1,x2,x3,x4,x5,x6,x7,x8,x9