c – 根据模板参数选择联合成员

前端之家收集整理的这篇文章主要介绍了c – 根据模板参数选择联合成员前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在处理C中的联合,我希望有一个函数模板,它可以根据模板参数访问活动的union成员.

代码就像(doSomething只是一个例子):

union Union {
  int16_t i16;
  int32_t i32;
};

enum class ActiveMember {
    I16,I32
}

template <ActiveMember M>
void doSomething(Union a,const Union b) {
  selectMemeber(a,M) = selectMember(b,M);
  // this would be exactly (not equivalent) the same
  // that a.X = b.X depending on T.
}

为了实现这一点,我只发现了一些糟糕的黑客攻击,比如专业化,或者是一种不同类的访问和分配方式.

我错过了什么,这样的事情应该用其他方法来做?

解决方法

可能性1

而不是使用枚举,您可以使用简单的结构来选择成员:

typedef short int16_t;
typedef long int32_t;

union Union {
    int16_t i16;
    int32_t i32;
};

struct ActiveMemberI16 {};
struct ActiveMemberI32 {};

template <typename M>
void doSomething(Union& a,Union b) {
    selectMember(a,M()) = selectMember(b,M());

    // this would be exactly (not equivalent) the same
    // that a.X = b.X depending on T.
}

int16_t& selectMember(Union& u,ActiveMemberI16)
{
    return u.i16;
}

int32_t& selectMember(Union& u,ActiveMemberI32)
{
    return u.i32;
}

int main(int argc,char* argv[])
{
    Union a,b;
    a.i16 = 0;
    b.i16 = 1;
    doSomething<ActiveMemberI16>(a,b);
    std::cout << a.i16 << std::endl;

    b.i32 = 3;
    doSomething<ActiveMemberI32>(a,b);
    std::cout << a.i32 << std::endl;
    return 0;
}

这需要为union中的每个成员定义struct和selectMember方法,但至少可以在许多其他函数中使用selectMember.

请注意,我将参数转换为引用,如果不合适,您可以调整它.

可能性2

通过将union指针强制转换为所需的类型指针,您可以使用单个selectMember函数.

typedef short int16_t;
typedef long int32_t;

union Union {
    int16_t i16;
    int32_t i32;
};
template <typename T>
T& selectMember(Union& u)
{
    return *((T*)&u);
}

template <typename M>
void doSomething(Union& a,Union b) {
    selectMember<M>(a) = selectMember<M>(b);

    // this would be exactly (not equivalent) the same
    // that a.X = b.X depending on T.
}



int _tmain(int argc,_TCHAR* argv[])
{
    Union a,b;
    a.i16 = 0;
    b.i16 = 1;

    doSomething<int16_t>(a,b);
    std::cout << a.i16 << std::endl;

    b.i32 = 100000;
    doSomething<int32_t>(a,b);
    std::cout << a.i32 << std::endl;
    return 0;
}
原文链接:https://www.f2er.com/c/111154.html

猜你在找的C&C++相关文章