Я хотел бы создать это в «универсальном» алгоритме, который может принимать любое перечисление (enum_type2 вместо только enum_type и т. Д.), Но я не совсем уверен, как это сделать с нетиповым шаблономparams, или это даже возможно.
Вы пометили C ++ 11, поэтому вы не можете использовать auto
в качестве параметра типа шаблона (доступно начиная с C ++ 17), поэтому у вас естьвыразить, как параметр типа шаблона, enum
, который вы используете.
Лучшее, что я могу себе представить, это следующее
#include <iostream>
enum enum_type : std::size_t
{ DEFAULT = 0, ONE, TWO, THREE, FOUR, MAX = FOUR, };
enum enum_type2 : std::size_t
{ DEFAULTbis = 0, ONEbis, TWObis, THREEbis, MAXbis = THREEbis, };
template <typename ET, ET F>
struct traits
{ static void do_something() {} };
template <typename ET, ET F, typename TT = traits<ET, F>, typename = void>
struct attr_engine
{
static void set ()
{
std::cout << "Number: " << F << std::endl;
TT::do_something();
constexpr ET NEXT_FIELD = static_cast<ET>(F - 1u);
attr_engine<ET, NEXT_FIELD>::set();
}
};
template <typename ET, ET F>
struct attr_engine<ET, F, traits<ET, F>,
typename std::enable_if<0u == F>::type>
{ static void set() { std::cout << "Reached the end" << std::endl; } };
int main ()
{
attr_engine<decltype(MAX), MAX>::set();
attr_engine<decltype(MAXbis), MAXbis>::set();
}
Если (когда) вы можете использовать C ++17, все становится проще
#include <iostream>
enum enum_type : std::size_t
{ DEFAULT = 0, ONE, TWO, THREE, FOUR, MAX = FOUR, };
enum enum_type2 : std::size_t
{ DEFAULTbis = 0, ONEbis, TWObis, THREEbis, MAXbis = THREEbis, };
template <auto>
struct traits
{ static void do_something() {} };
template <auto F, typename TT = traits<F>, typename = void>
struct attr_engine
{
static void set ()
{
std::cout << "Number: " << F << std::endl;
TT::do_something();
attr_engine<static_cast<decltype(F)>(F - 1u)>::set();
}
};
template <auto F>
struct attr_engine<F, traits<F>, typename std::enable_if<0u == F>::type>
{ static void set() { std::cout << "Reached the end" << std::endl; } };
int main ()
{
attr_engine<MAX>::set();
attr_engine<MAXbis>::set();
}