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; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |