C ++: Использовать отражение для зацикливания элементов в структуре? - PullRequest
0 голосов
/ 02 апреля 2019

У меня есть следующие коды, которые работают нормально. В основном он проходит по всем указателям в my_struct, применяет my_fun к каждому указателю и присваивает соответствующий вывод my_array.

   enum class MyEnum {
       head = 0,
       tail = 1,
       left_head = 2,
       left_tail = 3,
       right_head = 4,
       right_tail = 5,
   };

    auto head_ptr = my_struct.head_;
    auto tail_ptr = my_struct.tail_;
    auto left_head_ptr = my_struct.left_head_;
    auto left_tail_ptr = my_struct.left_tail_;
    auto right_head_ptr = my_struct.right_head_;
    auto right_tail_ptr = my_struct.right_tail_;

    if (head_ptr) {
        my_array[static_cast<size_t>(MyEnum::head)] = my_fun(head_ptr);
    }

    if (tail_ptr) {
        my_array[static_cast<size_t>(MyEnum::tail)] = my_fun(tail_ptr);
    }

    if (left_head_ptr) {
        my_array[static_cast<size_t>(MyEnum::left_head)] = my_fun(left_head_ptr);
    }

    if (left_tail_ptr) {
        my_array[static_cast<size_t>(MyEnum::left_tail)] = my_fun(left_tail_ptr);
    }

    if (right_head_ptr) {
        my_array[static_cast<size_t>(MyEnum::right_head)] = my_fun(right_head_ptr);
    }

    if (right_tail_ptr) {
        my_array[static_cast<size_t>(MyEnum::right_tail)] = my_fun(right_tail_ptr);
    }

Мне интересно, есть ли более элегантный способ сделать это? Может быть, что-то вроде отражения в Java? Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

Я бы порекомендовал просто использовать карту или unordered_map, в зависимости от вашего точного использования.

struct my_struct {
  std::map<MyEnum, Value* ptr> values;
}

Тогда ваш построитель массива станет:

for (const auto&[key, value] : my_struct_instance.values) {
  my_array[static_cast<size_t>(key)] = my_fun(value);
}
0 голосов
/ 02 апреля 2019

Самый простой способ - использовать apply и tie:

auto assign = [](std::size_t ith, auto& member) {
    if (member) {
        my_array[ith] = my_fun(member);
    }
};

std::apply(
    [&assign](auto&... members) {
        std::size_t ith = 0;
        (assign(ith++, members), ...);
    },
    std::tie(
        my_struct.head_,
        my_struct.tail_,
        my_struct.left_head_,
        my_struct.left_tail_,
        my_struct.right_head_,
        my_struct.right_tail_
    )
);

В C ++ 20, однако, вы можете использовать операторы расширения для итерации по агрегатному типу:

std::size_t ith = 0;
for...(auto& member : my_struct) {
    if (member) {
        my_array[ith++] = my_fun(member);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...