加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 03:32:16 所属栏目:百科 来源:网络整理
导读:我正在处理C中的联合,我希望有一个函数模板,它可以根据模板参数访问活动的union成员. 代码就像(doSomething只是一个例子): union Union { int16_t i16; int32_t i32;};enum class ActiveMember { I16,I32}template ActiveMember Mvoid doSomething(Union a,
我正在处理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;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读