цикл по нескольким перечислениям - PullRequest
3 голосов
/ 03 июля 2019

Как бы я зацикливался на нескольких перечислениях.

Я бы хотел, чтобы перечисления были внутри скелета

Не совсем уверен, как сконструировать мои перечисления, чтобы они были в таком контейнере, как этот

Тогда не совсем уверен, как я мог бы зациклить его, чтобы получить каждый из типов

Ответы [ 2 ]

0 голосов
/ 03 июля 2019

У меня есть подход метапрограммирования, основанный на кортеже

#include <tuple>
#include <type_traits>
#include <utility>
#include <iostream>

struct foo_enumerator {

enum class foo {
    ONE = 0 ,
    TWO =  1,
    THREE = 2
};

static constexpr auto reflect = std::make_tuple(
                                            foo::ONE,
                                            foo::TWO,
                                            foo::THREE);

};

struct bar_enumerator {
    enum class bar {
        FOUR = 4,
        FIVE =  5,
        SIX = 6
    };

    static constexpr auto reflect = std::make_tuple(
                                            bar::FOUR,
                                            bar::FIVE,
                                            bar::SIX);

};

// a tuple for_each implementation
// can be replaced with something else, like boost hana for_each for example
namespace detail {

// workaround for default non-type template arguments
template<std::size_t I>
using index_t = std::integral_constant<std::size_t, I>;

// process the `From::value`-th element
template<typename FromIndex,
         typename ToIndex,
         typename Tuple,
         typename UnaryFunction>
struct for_each_t {
    constexpr UnaryFunction&& operator()(Tuple&& t, UnaryFunction&& f) const
    {
        std::forward<UnaryFunction>(f)(
                std::get<FromIndex::value>(std::forward<Tuple>(t)));
        return for_each_t<index_t<FromIndex::value + 1>,
                          ToIndex,
                          Tuple,
                          UnaryFunction>()(
                std::forward<Tuple>(t), std::forward<UnaryFunction>(f));
    }
};

// specialization for empty tuple-likes
template<typename FromIndex, typename Tuple, typename UnaryFunction>
struct for_each_t<FromIndex, index_t<0>, Tuple, UnaryFunction> {
    constexpr UnaryFunction&& operator()(Tuple&&, UnaryFunction&& f) const
    {
        return std::forward<UnaryFunction>(f);
    }
};

// specialization for last element
template<typename ToIndex, typename Tuple, typename UnaryFunction>
struct for_each_t<index_t<ToIndex::value - 1>, ToIndex, Tuple, UnaryFunction> {
    constexpr UnaryFunction&& operator()(Tuple&& t, UnaryFunction&& f) const
    {
        std::forward<UnaryFunction>(f)(
                std::get<ToIndex::value - 1>(std::forward<Tuple>(t)));
        return std::forward<UnaryFunction>(f);
    }
};

}  // namespace detail

template<typename Tuple, typename UnaryFunction>
constexpr UnaryFunction for_each(Tuple&& t, UnaryFunction&& f)
{
    return detail::for_each_t<detail::index_t<0>,
                              detail::index_t<std::tuple_size<
                                  std::remove_reference_t<Tuple>
                              >::value>,
                              Tuple,
                              UnaryFunction>()(
            std::forward<Tuple>(t), std::forward<UnaryFunction>(f));
}


int main(int argc, const char** argv)
{

    constexpr auto all = std::tuple_cat( foo_enumerator::reflect, bar_enumerator::reflect );

    for_each(all, [](auto e_value)  {
            std::cout << "Enumeration value: " << static_cast<unsigned int>(e_value) << std::endl;
    });
}

PS Да, нам нужно отражение времени компиляции в C ++ (вероятно, C ++ 23)

0 голосов
/ 03 июля 2019

Короткий ответ: ты не можешь.По крайней мере, не в C ++ (пока ™).

Чтобы сделать то, что вы описываете, вам нужны размышления.Отражения позволяют динамически перемещаться по объектам во время выполнения.

C # /. Net обеспечивает это.Вот пример на C #.

enum MyEnum { Test, Test1, Test2, Another, One, Bites, The, Dust }
foreach (var value in typeof(MyEnum).GetEnumValues()) {
    WriteLine(value.ToString());
}

Я не уверен, что C ++ когда-либо примет отражения, будь то в этой форме или другом.

Извините, если это не таквсе ответы, которые вы хотели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...