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

2024-03-11

我正在处理 C++ 中的联合,我想要一个函数模板,它可以根据模板参数访问活动联合成员。

代码类似于(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;
}

这需要为联合中的每个成员定义一个结构体和一个 selectMember 方法,但至少您可以在许多其他函数中使用 selectMember。

请注意,我将参数转为参考,如果不合适,您可以调整它。

可能性2

通过将联合指针转换为所需的类型指针,您可以使用单个 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;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

根据模板参数选择联合成员 的相关文章

  • MVC Core IActionResult 含义

    什么是IActionResult 我尝试查看 MSDN 和其他网站 但需要通用 常见 易于理解的答案 MSDN IActionResult https learn microsoft com en us dotnet api microso
  • 中间件 API 的最佳实践是什么? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我们正在开发一个中间件 SDK 采用 C 和 Java 语言 供游戏开发人员 动画软件开发人员 阿凡达开
  • OpenCV Visual Studio ntdll.dll

    我尝试在 Visual Studio 2013 上使用 OpenCV 2 4 10 创建一个项目 但由于以下异常 到目前为止我运气不佳 请建议帮助 TIA letstryitonemoretime exe Win32 Loaded C Us
  • CMake 和 Visual Studio:如何获得快速、安静的命令行构建?

    我有一个 cmake 项目 它成功地完成了我想要的一切 但我有大约 100 个文件 当我只需要重新编译一个文件时 我厌倦了每次看到生成的巨大输出 每个文件 30 行 明确地说 我正在编译cmake build 得到这个结果 我需要传递给编译
  • 如何在 MFC 中调整对话框大小时移动控件?

    我已经在 MFC 中创建了对话框视图 从下图中可以清楚地看到 如滑块控件和编辑框等 当我调整对话框大小时 这些控件不会移动 在此输入图像描述 https i stack imgur com 7OxAK jpg 我想移动控件以适应对话框 但不
  • 避免集合已修改错误

    Issue 我有以下代码 foreach var ItemA in GenericListInstanceB ItemA MethodThatCouldRemoveAnyItemInGenericListInstanceB 显然我得到一个错
  • 将列表(对象)转换为列表(字符串)

    有没有办法转换List of Object to a List of String 在 c 或 vb net 中而不迭代所有项目 幕后迭代很好 我只想要简洁的代码 Update 最好的方法可能就是进行新的选择 myList Select f
  • 具有多重继承的类的 sizeof

    首先 我知道 sizeof 取决于机器和编译器的实现 我使用的是 Windows 8 1 x64 gcc 5 3 0 没有标志传递给编译器 我从大学讲座中得到了以下代码 include
  • 返回指向 std::vector 中的对象的 a

    我有一个关于返回对向量元素的引用的非常基本的问题 有一个向量vec存储类的实例Foo 我想访问这个向量中的一个元素 不想使用向量索引 我应该如何编码该方法getFoo here include
  • 'goto *foo' 其中 foo 不是指针。这是什么?

    我正在玩标签作为值 https gcc gnu org onlinedocs gcc Labels as Values html并最终得到这段代码 int foo 0 goto foo 我的 C C 经验告诉我 foo means dere
  • Azure 2012 年 10 月 SDK 损坏 UseDevelopmentStorage=true

    有人尝试过使用 usedevelopmentstorage true 连接字符串的 2012 年 10 月 Azure sdk 吗 CloudStorageAccount Parse UseDevelopmentStorage true 抛
  • 如何用C++解析复杂的字符串?

    我试图弄清楚如何使用 解析这个字符串sstream 和C 其格式为 string int int 我需要能够将包含 IP 地址的字符串的第一部分分配给 std string 以下是该字符串的示例 std string 127 0 0 1 1
  • .Net Core 中的脚手架以及解决方案中的多个项目

    我创建了一个针对 net461 的 Net Core MVC6 应用程序 我使用了一个我非常熟悉的项目结构 其中我将数据 模型和服务类放置在单独的类库项目中 并且 Web 项目引用这些项目 当我尝试搭建控制器时 我收到一条错误 指出我正在搭
  • Qt mouseReleaseEvent() 未触发?

    我有一个显示图片的库 我们称之为 PictureGLWidget 其中 class PictureGLWidget public QGLWidget 所以 PictureGLWidget 扩展了 QGLWidget 在PictureGlWi
  • Qt:将拖放委托给子级的最佳方式

    我在 QWidget 上使用拖放 我重新实现了 DragEnterEvent dragLeaveEvent dragMoveEvent 和 dropEvent 效果很好 在我的 QWidget 中 我有其他 QWidget 子级 我希望它们
  • 如何解释“错误C2018:未知字符'0x40'?[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 在编译一些代码时 我收到以下信息 错误 C2018 未知字符 0x40 我想知道如何解决这样的问题 这是我要开始的地方
  • Django - 渲染到字符串无法加载 CSS

    我正在尝试使用 Django 1 8 render to string 通过管理命令将 html 转换为 pdf 而不是使用 View request 以下代码可以将模板转换为 pdf 但它无法将 CSS 加载到模板中 def html t
  • 在 try catch 块中返回到 catch 内是否不好?这是很好的做法

    在 try catch 块中从 C 中的 catch 块返回值是不好的做法吗 try Some code return 1 catch return 0 哪种使用 try catch 的方法是好的做法 不需要 只要返回的值是你想要的 你可以
  • 将小数格式化为两位或整数

    对于 10 我想要 10 而不是 10 00 对于 10 11 我想要 10 11 没有代码可以实现吗 即通过指定格式字符串类似于 0 N2 decimal num 10 11M Console WriteLine num ToString
  • 致命错误 C1001:编译器中发生内部错误(编译器文件“msc1.cpp”,第 1325 行)

    当我编译代码时 错误指向以下类 该错误在两行上突出显示 如下所示 tm validFrom tm validUntil struct t SslCertData final struct t Contact TCHAR Organizati

随机推荐