模板实例化检查类中存在的成员

2023-12-03

我有一组类,其中有一个或多个类型为memberA、memberB、memberC 的成员。并非所有班级都有所有成员。我想创建一个模板来设置成员,例如

template <typename T>
void setAttributes(t & myClass, typeA memA, typeB memB, typeC memC)
{
  myClass.memberA = memA;
  myClass.memberB = memb;
  myClass.memberC = memC;
}

显然,当尝试实例化缺少其中一个成员的类时,这将在编译时失败。是否有 #if 或类似的东西可以允许对表单的条件编译进行检查

#ifdef myClass.memberA
  myClass.memberA = memA;
#endif

我现在无法实际尝试此操作或类似的操作,我想知道是否有有效的设置方法。

我已经看到对 SFINAE 的引用(“替换失败不是错误。”),但我不确定在这种情况下如何使用它。下面的建议正确吗?

替换失败不是错误示例似乎暗示我应该为每个成员创建一个单独的函数,并在没有该成员的情况下使用重复的函数。

template <typename T>
void setMemberA(T & myClass, typeA memA)
{
  myClass.memberA = memA;
}

template <typenum T>
void setMemberA(T & myClass)
{
  // This is a dummy template to avoid a compilation problem
}

这是一个可能的set_memberA_if_exists执行:

namespace details {
    template<class T>
    auto set_memberA_if_exists_impl(T & myClass, typeA memA, int) 
         -> decltype(myClass.memberA = memA, void()) {
        myClass.memberA = memA;
    }

    template<class T>
    void set_memberA_if_exists_impl(T & myClass, typeA memA, long) {}
}

template<class T>
void set_memberA_if_exists(T & myClass, typeA memA) {
     details::set_memberA_if_exists_impl(myClass, memA, 0);
}

解释:

SFINAE 仅适用于函数模板的签名,而不适用于函数模板的主体,因此技巧是将检查编码在函数模板签名内。使用 C++11 尾随返回类型很容易 --> decltype(myClass.memberA = memA, void())。如果表达式myClass.memberA = memA无法编译,然后会导致替换失败并从重载集中删除函数模板。这样就可以调用set_memberA_if_exists_impl在这种情况下仍然会编译,我们还提供了另一个不执行任何操作的重载。

当这两个重载都可行时,我们还需要一种方法来区分它们。这是通过引入第三个参数来完成的。 do-something 重载的第三个参数的类型是int,而无所事事的过载是long。通过提供0 (an int)作为我们调用它时的第三个参数,我们确保在可行时首选 do-something 重载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

模板实例化检查类中存在的成员 的相关文章

随机推荐

  • 如何使用 fastcgi 和 perlbrew 为在 nginx 上运行的 Perl Catalyst 应用程序创建初始化脚本

    我正在寻找一个 initscript 以便在运行 nginx 作为 Perl Catalyst 应用程序代理的网络服务器上使用 perlbrew 我目前正在尝试通过以下方式启动应用程序 source PERLBREW execute per
  • this:不能在静态上下文中使用 this

    你能帮我用下面的代码吗 错误是 无法在静态上下文中使用此 public class Sample2 param args public static void main String args Sample2 sam new Sample2
  • 将 boost numpy 与 Visual Studio 2019 和 python 3.8 结合使用

    我想将 Boost Numpy Boost 版本 1 72 与 Visual Studio 2017 和 Python 3 8 结合使用 在我的测试程序中 我收到链接错误 boost numpy38 vc141 mt gd x32 1 72
  • 如何通过代码打开窗口的系统菜单?

    我有一个 C WinForms 无边框窗口 我重写 WndProc 并处理 WM NCHITTEST 消息 对于这种形式的区域 我的命中测试函数返回 HTSYSMENU 双击该区域成功关闭窗体 但右键单击它不会显示窗口的系统菜单 在任务栏中
  • Core Data SUBQUERY 和 NSFetchedResultsController 的键路径错误

    如果这是重复的 我们深表歉意 20 分钟的搜索没有找到确切的情况或解决方案 我有一个包含三个类的核心数据堆栈XClass YClass and ZClass XClass与 具有一对多关系YClass YClass与 具有一对多关系ZCla
  • 为什么此 toDataURL 行是安全错误?

    如果将来自另一个站点的图像加载到页面 然后将其作为合成中的部分成分写入画布 请使用 context drawImage image 0 0 w h 似乎任何不安全的事情都已经在画布上发生了 那为什么会 window location can
  • 长按NavigationView只能作用于左侧部分,不能作用于所有NavigationLink?

    下面是一个NavigationView 视图弹出到Destination2当长按 NavigationLink 并Destination1正常点击时 但图中NavigationLink的右侧区域无法长按 有谁知道原因吗 谢谢 import
  • WIX:继续安装之前应关闭以下应用程序

    我的应用程序有托盘图标 当我卸载它时 我有一个窗口 其中建议关闭 my tray app exe 带有文本 在继续安装之前应关闭以下应用程序 我使用wix CloseApplication Element Util Extension 来关
  • 如何使用 javafx-maven-plugin 运行包含 jfoenix 的 Maven java fx 项目

    我试图创建编译我的应用程序并创建一个可执行文件 目前我认为最好使用的工具是 javafx maven plugin 我无法让它工作 所以我从根据此创建项目时生成的基本代码开始 https www youtube com watch v 4v
  • Google Gmail SMTP 设置不允许我使用 PHPMailer 发送电子邮件

    我在 Gmail 上创建了一个帐户 因为前一个帐户也给我带来了同样的问题 以便我的应用程序可以使用 google smtp 服务器发送电子邮件 我正在使用 PHPMailer 库并要求它显示任何日志错误 我总是收到类似的消息 它略有不同 有
  • Android 中的 RTSP 客户端

    可能有人问过同样的问题 但我没有找到任何适合我的解决方案 我正在尝试在 android 中播放 RTSP 流 服务器是 Darwin 流服务器 目前我尝试了VideoView和MediaPlayer 当我使用3G时 这两个都工作正常 但有时
  • 确定 PHP 调用函数的位置

    你们知道我如何从哪个文件中确定该函数内部调用的函数吗 我正在考虑使用 debug backtrace 但这看起来并不是一种优雅的方式 而且他们还在另一个问题中列举了其他原因here 那么还有什么其他选择呢 多谢 我前段时间从某个地方借用了这
  • 在 Angular2 路由中使用 Resolve

    在 Angular 1 中我的配置如下所示 routeProvider when news templateUrl newsView html controller newsController resolve message functi
  • Umbraco 7 更新 Umbraco 路线

    我正在尝试创建一个 Umbraco 7 MVC 应用程序 在此过程中 我希望能够创建在幕后管理数据的自定义控制器 通过我的研究 我发现使用 SurfaceController 是最成功的 但是 该路线将 umbraco surface 添加
  • 如何在 apache 服务器上运行 socket.io(仅限客户端)

    我想在我的 apache 服务器上运行 socket io 的客户端 我已将 socket io 目录上传到我的网络服务器 并尝试了主站点的简单客户端连接示例套接字 io但它不起作用 我不知道需要什么才能让它工作并连接我正在运行的服务器 我
  • 将参数传递给返回集合的 OData (GET) 方法

    我在用OData v3 如何将参数传递给OData控制器并返回一个集合 我正在尝试做的示例 EnableQuery AllowedQueryOptions AllowedQueryOptions All public IQueryable
  • Firestore Cloud Function 空集合

    我有一个问题困扰了我好几天 我正在尝试创建一个从 Firestore 数据库读取的 Firebase Cloud 函数 我的 Firestore 数据库如下所示 问题是我无法列出users像这样 db collection users ge
  • Azure DevOps管道:取消队列中的多个待处理作业

    在 Azure DevOps 管道中 如何取消作业池的所有待处理作业 我有很多工作在排队 但看不到在哪里可以取消我正在等待的所有工作 Azure Devops 尚不具备从 UI 部分批量取消所有待处理作业的功能 您可以编写脚本来调用rest
  • 我可以有一个空的 Java 类吗?

    我正在创建一个基于网格的游戏 我需要实现一组在网格内占据随机位置的障碍物 我创建了一个抽象类ALifeForm 它保存网格中每个项目的通用方法 显然 抽象类无法初始化 所以我要创建一个新类AObstacle 这将延长ALifeForm 唯一
  • 模板实例化检查类中存在的成员

    我有一组类 其中有一个或多个类型为memberA memberB memberC 的成员 并非所有班级都有所有成员 我想创建一个模板来设置成员 例如 template