根据选择的硬件类型修改枚举值

Changing enum values based on HW selection

本文关键字:修改 枚举 类型 硬件 选择      更新时间:2023-10-16

设计一个函数的最佳方法是什么?例如,允许的enum值根据所选择的硬件而变化。函数可能看起来像这样,这不会编译,但希望你能明白。

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);
}

有谁知道一种方法,使它更好地选择基于类型的元素?我宁愿以某种方式链接那些甚至元素的类型在编译时,而不是选择他们在运行时,使用一个函数,无论如何,使这段代码更愚蠢的证明?

瞎猜,因为我不确定你到底想做什么。看起来您想要做一些编译时的决定,可能看起来像这样:

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");
}

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

如果你想在编译时更灵活地构造数组,我建议看看我的这个问题,我在那里描述了在编译时构造静态数组的tmp函数:g++(4.7.2)在编译时初始化静态数组时的错误或特性?

编辑:你说你对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;