这是一些对模板进行递归的示例代码的片段。我正在尝试创建一种算法,该算法接受任何枚举(从0...n
开始,依次使用)并基于这些值使用特征执行“算法”(通过将最大枚举减去1来递归执行此操作)。
#include <iostream>
using namespace std;
enum enum_type : size_t
{
DEFAULT = 0,
ONE = 1,
TWO = 2,
THREE = 3,
FOUR = 4,
MAX = FOUR,
};
template < enum_type F >
struct traits;
template < >
struct traits<ONE>
{
static void do_something() {}
};
template < >
struct traits<TWO>
{
static void do_something() {}
};
template < >
struct traits<THREE>
{
static void do_something() {}
};
template < >
struct traits<FOUR>
{
static void do_something() {}
};
template < enum_type F, typename TT = traits<F> >
struct attr_engine
{
static void set() {
printf("Number: %lu ", F);
TT::do_something();
// get a compile error of trying to subtract an enum to an integer
constexpr enum_type NEXT_FIELD = static_cast<enum_type>(F - 1);
attr_engine<NEXT_FIELD>::set();
return;
}
};
template < >
struct attr_engine<DEFAULT, traits<DEFAULT>>
{
static void set() {
printf("Reached the end");
return;
}
};
int main()
{
attr_engine<MAX>::set();
return 0;
}
我想将其创建为一个“通用”算法,该算法可以采用任何枚举(enum_type2
而非仅enum_type
等),但我不是非常确定如何使用非类型模板参数执行此操作,甚至有可能。
我不能使用typename,因为我使用的是非类型模板参数。
template < typename F, typename TT = traits<F> >
struct attr_engine
作为替代方案,我考虑过可能使用std::size_t
:
template < size_t F, typename TT = traits<F> >
struct attr_engine
但是,我坚持尝试创建一个可以推论为适当特性的通用F
。我需要一些新方法。我担心这样做会导致我转换看起来很乱的输入非模板参数。
enum enum_type2
{
DEFAULT_ENUM2,
ONE_VAL,
TWO_VAL,
THREE_VAL,
FOUR_VAL,
ENUM2_MAX = FOUR_VAL,
};
int main()
{
attr_engine<static_cast<sizet>(ENUM2_MAX)>::set();
return 0;
}
答案 0 :(得分:1)
我想将其创建为可以接受任何枚举(“ enum_type2”而不是“ enum_type”等)的“通用”算法,但是我不太确定如何使用非类型模板参数来执行此操作,或者甚至有可能。
您标记了C ++ 11,因此不能使用auto
作为模板类型参数(从C ++ 17开始可用),因此必须将{{1 }}您正在使用。
我能想象的最好的是以下
enum
(如果)可以使用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 <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();
}