根据硬件选择更改枚举值

时间:2014-06-30 11:02:35

标签: c++ function

设计一个函数的最佳方法是,允许的枚举值根据所选的硬件而改变。该函数可能看起来像这样,这不会编译,但希望你能得到这个想法。

enum class EHWUnit
{
Unit0,
Unit1,
Unit2
};

enum class EHWType
{
Type1,
Type2,
Type3,
Type4
};

SelectHWinput( const EHWUnit aUnit, const EHWType aHWType, const unit8_t aSelect )
{

if( aHWType & 1 == 0)

ArrayIS( 2,4,6,8,10)

else

 ArrayIS( 1,3,5,7,9)

 element = ArrayIS(aSelect)

 WriteToRegister( Address, bits, element);
}

有没有人知道如何更好地根据类型选择元素?我宁愿以某种方式在编译时将这些偶数元素链接到类型而不是在运行时选择它们,使用一个函数是否仍然可以使这个代码更加简单?

1 个答案:

答案 0 :(得分:0)

在黑暗中拍摄,因为我不确定你想要做什么。 看起来你想做一些编译时的决定,看起来像这样:

enum EHWUnit
{
    Unit0,
    Unit1,
    Unit2
};

enum EHWType
{
    Type1,
    Type2,
    Type3,
    Type4
};


template <int Select>
struct ArrayIS
{
    static constexpr int const array[] = {1, 3, 5, 7, 9};
};
template <int Select>
constexpr int const ArrayIS<Select>::array[];

template <>
struct ArrayIS<0>
{
    static constexpr int const array[] = {2, 4, 6, 8, 10};
};    
constexpr int const ArrayIS<0>::array[];

template <EHWUnit aUnit, EHWType aHWType, int aSelect>
struct SelectHWinput
{
    static constexpr int get()
    {
        return ArrayIS<static_cast<int>(aHWType) & 1>::array[aSelect];
    }
};

int main()
{
    // To illustrate that the value is selected at compile-time, a
    // static assertion that will always fail:
    static_assert(SelectHWinput<Unit0, Type1, 0>::get() < 0, "Works, value selected at compile-time");
}

在上面的代码中,Template Metaprogramming(TMP)用于在编译时选择其中一个数组的值。通过提供Select模板非类型参数来选择正确的数组。因为这些数组声明为constexpr,所以可以使用constexpr成员函数在编译时提取其中一个元素。 static_assert证明它有效。

如果你想在编译时更灵活地构造数组,我建议看看我的这个问题,在那里我描述了TMP-functors在编译时构造静态数组: g++ (4.7.2) bug or feature, when initializing static arrays at compile-time?

编辑: 您说您对Array实施感兴趣:

template <typename T, size_t Count, template <typename, T> class Function, T Current, T ... Elements>
struct Array_: public Array_<T, Count - 1, Function, Function<T, Current>::result, Elements ..., Current>
{};


template <typename T, template <typename, T> class Function, T Current, T ... Elements>
struct Array_<T, 0, Function, Current, Elements...>
{
    constexpr static std::array<T, sizeof...(Elements)> array = {{Elements ...}};
};

template <typename T, size_t Count, T Start = T(), template <typename, T> class Function = Null>
struct Array: public Array_<T, Count, Function, Start>
{};

这里,最后一个是你将使用的那个,使用Template Metaprogramming仿函数告诉编译器如何从前一个元素生成下一个元素。这是一个限制,但它是我当时能想到的最好的。

您可以使用三个简单的仿函数:

template <typename T, T Value>
struct Null
{
    enum { result = Value };
};

template <typename T, T Value>
struct Increment
{
    enum { result = Value + 1 };
};

template <typename T, T Value>
struct Decrement
{
    enum { result = Value - 1 };
};

例如,如果您需要一个增量值为1到100的数组,则可以执行以下操作:

std::array<int, 100> arr = Array<int, 100, 1, Increment>::array;

然后在编译时分配并填充此数组。