如果参数有成员变量则特殊化函数

2024-01-14

我有一个模板化的错误报告函数,因为它可以报告许多不同消息类别的错误:

template <typename MSG>
void reportErr(const MSG& msg)
{
    std::cout << "ERROR: " << msg.error << std::endl;
}

但是,某些类型的消息具有可以报告的更详细的错误或其他专门的错误报告,例如

template<>
void reportErr(const SpecificMsg& msg)
{
    std::cout << "ERROR: " << msg.error;
    std::cout << ", details: " << msg.details << std::endl;
}

由于有很多类型,例如SpecificMsg,我不想为每种类型创建单独的模板专业化。是否可以为具有以下特征的任何类型创建通用专业化/部分专业化:.details成员变量?

如果可能的话,我想要一种方法来普遍做到这一点(所以一个专业化,如果它有.details,如果有则另一种.other_info, etc).

Edit: 这是明确询问功能。我见过代码可以做类似的事情来专门化模板classes,但我从未遇到过可以满足我对非成员函数的要求的东西。我怀疑将用于类的方法转换为用于函数的方法并不难,但我一直无法弄清楚如何做到这一点。

Edit 2:我的 gcc 版本(4.6.3)似乎不支持完整的 C++11 标准,所以void_t http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf“重复”问题中提到的选项对我不起作用。我的编译器抱怨“‘类型’之前预期有嵌套名称说明符”等,甚至不让我定义 void_t。因此,我从我的问题中删除了 C++11 标签。


我会为此使用 SFINAE。首先,我们定义两个函数,它们返回错误消息的字符串:

namespace detail
{
    // for messages with "details" member:
    template<typename MsgType>
    std::string makeMsgString(const MsgType& msg, decltype(MsgType::details)*)
    {
        return "Error: " + msg.error + ", details: " + msg.details;
    }

    // for messages without "details" member:
    template<typename MsgType>
    std::string makeMsgString(const MsgType& msg, ...)
    {
        return "Error: " + msg.error + ", no details";
    }
}

现在,这些函数可以这样使用:

struct NonSpecificMsg { std::string error; };
struct SpecificMsg { std::string error, details; };

template<typename MsgType>
void reportErr(const MsgType& msg)
{
    std::cout << detail::makeMsgString(msg, nullptr) << "\n";
}

int main()
{
    reportErr(NonSpecificMsg { "some error" }); // 1
    reportErr(SpecificMsg { "some other error", "some details" }); // 2
    return 0;
}

这里会发生什么?

致电 1):NonSpecificMsg没有details成员,因此第一个重载不存在。自从MsgType::details不存在,decltype(MsgType::details)*不是有效类型。 SFINAE 会导致该定义被忽略,而不是在编译期间引发错误。 只有重载2),不访问details member.

致电2):SpecificMsg has details,因此编译器会考虑这两个重载。但是,可变参数函数重载(第二个)的优先级始终低于任何其他匹配重载,因此选择第一个。

Edit:这是 C++11 解决方案。很遗憾,decltype在 GCC 4.8 中引入。

Edit 2:事实证明decltype can与 GCC 4.6 一起使用(它是在版本 4.3 中引入的)。版本 4.8.1 更改了其语义,但在 OP 的情况下,以前的版本将起作用 - 请参阅GCC 的 C++ 状态页面 https://gcc.gnu.org/projects/cxx-status.html

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

如果参数有成员变量则特殊化函数 的相关文章

  • InvalidOperationException - 对象当前正在其他地方使用 - 红十字

    我有一个 C 桌面应用程序 其中我连续创建的一个线程从源 实际上是一台数码相机 获取图像并将其放在 GUI 中的面板 panel Image img 上 这必须是另一个线程 如它是控件的代码隐藏 该应用程序可以工作 但在某些机器上 我会在随
  • 每个托管线程是否都有自己对应的本机线程?

    我想知道是否在 Net 中创建托管线程 通过调用Thread Start 导致在后台创建一个本机线程 那么托管线程是否有对应的本机线程呢 如果是 当托管线程等待或睡眠时 是否意味着相应的本机线程也在等待或睡眠 是的 NET 线程映射到所有当
  • 使用 std::packaged_task/std::exception_ptr 时,线程清理程序报告数据争用

    我遇到了线程清理程序 TSan 的一些问题 抱怨某些生产代码中的数据争用 其中 std packaged task 通过将它们包装在 std function 中而移交给调度程序线程 对于这个问题 我简化了它在生产中的作用 同时触发 TSa
  • MVC 在布局代码之前执行视图代码并破坏我的脚本顺序

    我正在尝试将所有 javascript 包含内容移至页面底部 我正在将 MVC 与 Razor 一起使用 我编写了一个辅助方法来注册脚本 它按注册顺序保留脚本 并排除重复的内容 Html RegisterScript scripts som
  • C中的malloc内存分配方案

    我在 C 中尝试使用 malloc 发现 malloc 在分配了一些内存后浪费了一些空间 下面是我用来测试 malloc 的一段代码 include
  • 错误:表达式不产生值

    我尝试将以下 C 代码转换为 VB NET 但在编译代码时出现 表达式不产生值 错误 C Code return Fluently Configure Mappings m gt m FluentMappings AddFromAssemb
  • 在 C 中匹配二进制模式

    我目前正在开发一个 C 程序 需要解析一些定制的数据结构 幸运的是我知道它们是如何构造的 但是我不确定如何在 C 中实现我的解析器 每个结构的长度都是 32 位 并且每个结构都可以通过其二进制签名来识别 举个例子 有两个我感兴趣的特定结构
  • 如何创建包含 IPv4 地址的文本框? [复制]

    这个问题在这里已经有答案了 如何制作一个这样的文本框 我想所有的用户都见过这个并且知道它的功能 您可以使用带有 Mask 的 MaskedTestBox000 000 000 000 欲了解更多信息 请参阅文档 http msdn micr
  • 获取两个工作日之间的天数差异

    这听起来很简单 但我不明白其中的意义 那么获取两次之间的天数的最简单方法是什么DayOfWeeks当第一个是起点时 如果下一个工作日较早 则应考虑在下周 The DayOfWeek 枚举 http 20 20 5B1 5D 3a 20htt
  • 回发后刷新时提示确认表单重新提交。我做错了什么?

    我有一个以空白 默认状态启动的仪表板 我让用户能够将保存的状态加载到仪表板中 当他们单击 应用 按钮时 我运行以下代码 function CloseAndSave var radUpload find radUpload1ID var in
  • glibc 堆一致性检查

    根据2008年的帖子 我现在找不到 glibc 堆检查 http www gnu org s libc manual html node Heap Consistency Checking html在多线程环境中不起作用 现在还是2010年
  • qdbusxml2cpp 未知类型

    在使用 qdbusxml2cpp 程序将以下 xml 转换为 Qt 类时 我收到此错误 qdbusxml2cpp c ObjectManager a ObjectManager ObjectManager cpp xml object ma
  • 为什么调用非 const 成员函数而不是 const 成员函数?

    为了我的目的 我尝试包装一些类似于 Qt 共享数据指针的东西 经过测试 我发现当应该调用 const 函数时 会选择它的非 const 版本 我正在使用 C 0x 选项进行编译 这是一个最小的代码 struct Data int x con
  • 标准化 UTF-8 到底是什么?

    The 重症监护室项目 http userguide icu project org transforms normalization 现在也有一个PHP库 http us php net manual en class normalize
  • 如何在 Xaml 文本中添加电子邮件链接?

    我在 Windows Phone 8 应用程序中有一些大文本 我希望其中有电子邮件链接 例如 mailto 功能 这是代码的一部分
  • 使用自定义堆的类似 malloc 的函数

    如果我希望使用自定义预分配堆构造类似 malloc 的功能 那么 C 中最好的方法是什么 我的具体问题是 我有一个可映射 类似内存 的设备 已将其放入我的地址空间中 但我需要获得一种更灵活的方式来使用该内存来存储将随着时间的推移分配和释放的
  • 如何设置 log4net 每天将我的文件记录到不同的文件夹中?

    我想将每天的所有日志保存在名为 YYYYMMdd 的文件夹中 log4net 应该根据系统日期时间处理创建新文件夹 我如何设置它 我想将一天中的所有日志保存到 n 个 1MB 的文件中 我不想重写旧文件 但想真正拥有一天中的所有日志 我该如
  • Cmake 链接共享库:包含库中的头文件时“没有这样的文件或目录”

    我正在学习使用 CMake 构建库 构建库的代码结构如下 include Test hpp ITest hpp interface src Test cpp ITest cpp 在 CMakeLists txt 中 我用来构建库的句子是 f
  • 无法接收 UDP Windows RT

    我正在为 Windows 8 RT 编写一个 Windows Store Metro Modern RT 应用程序 需要在端口 49030 上接收 UDP 数据包 但我似乎无法接收任何数据包 我已按照使用教程进行操作DatagramSock
  • 如何将 PostgreSql 与 EntityFramework 6.0.2 集成? [复制]

    这个问题在这里已经有答案了 我收到以下错误 实体框架提供程序类型的 实例 成员 Npgsql NpgsqlServices Npgsql 版本 2 0 14 2 文化 中性 PublicKeyToken 5d8b90d52f46fda7 没

随机推荐

  • 如何避免在 Windows 中过度填充 PATH 环境变量?

    我想知道您使用什么方法来管理系统中的可执行文件 例如 我几乎可以通过命令行访问所有内容 但现在我遇到了路径字符串的限制 因此我无法添加更多目录 那么你有什么推荐呢 很久以前 我尝试在属于该路径的目录中使用可执行文件的软链接 但这种方法不起作
  • 是否可以对两个转换字符组合使用格式修饰符?

    我知道如何使用 log4j 输出类名和方法名 这两个字段都可以单独对齐和填充 例如这个模式 d ISO8601 5p 10C 1 10M m n 产生类似的东西 2012 09 20 08 25 12 111 WARN Class meth
  • Windows 无法在本地计算机上启动 Apache CouchDB 服务

    我已在 Windows 计算机上安装了 CouchDB 但在启动 CouchDB 服务时 我收到如下消息 Windows 无法在本地计算机上启动 Apache CouchDB 服务 该服务没有返回错误 这可能是 Windows 内部错误或内
  • 使用bundle运行gitlab服务器:命令未找到错误

    我不知道发生了什么 sudo 服务 gitlab 启动 Starting both the GitLab Unicorn and Sidekiqscript web line 21 bundle command not found 查看我的
  • 如何在 cygwin 上安装 cURL?

    我尝试在 cygwin 上启用curl 但它说bash curl command not found 如何在 cygwin 上安装curl 我刚刚遇到这个 1 从以下位置找到cygwin setup exe文件http cygwin com
  • 使文本高度为 div 的 100%?

    我正在尝试使文本的高度为 100 div但它不起作用 它只是变成了100 body font size 有什么办法让它跟随div高度吗 The div高度是整个页面的 4 当您调整大小 更改分辨率时 我不希望文本跟随它 为了获得我想要的结果
  • 是否可以在打字稿中创建动态 getter/setter?

    我是 TypeScript 新手 我正在尝试将我们的应用程序从 es2016 重写为 TypeScript 我的任务是拥有一个具有数据属性的类 并使数据对象中的每个元素可用作类属性 我被这段 JavaScript 代码困住了 for let
  • Django:关闭http响应消息的控制台输出

    所以我们用 django 制作了一个应用程序 每次收到请求时它都会在控制台上打印所有这些 http 响应消息 Date String GET urlpath blah blah 200 216 Date String DELETE anot
  • jQuery 数据表问题

    当使用jQuery 数据表插件 http datatables net 为什么我会收到此错误 k 未定义 style typeof e saved aaSorting 未定义 我发布这个答案是为了记录一些东西以供自己将来参考 我希望它能对其
  • EqualityComparer.Default 不够聪明

    我正在阅读源代码EqualityComparer
  • 带有圆角的 AppWidget 图像

    因此 我通过在应用程序的主布局中向用户显示的各种视图进行动画处理 在应用程序中动态创建图像 目前 我正在相对布局中生成场景 将布局图像作为位图 然后将位图保存到 SD 以便 appwidget 通过 uri 访问 这一切都工作得很好 但是
  • 如何在Linux内核中找到sk_buff的所有者套接字?

    我正在尝试找到一个的所有者插座sk buff举例来说 skb 我的最终目标是找到特定的 TCP 选项并以某种方式让用户空间应用程序知道 我打算在找到TCP选项时设置一个套接字选项并让用户空间应用程序调用getsockopt 因此我需要知道之
  • Python 字符串转 Int 或 None

    学习Python 有点卡壳 我正在尝试将变量设置为等于int stringToInt 或者如果字符串为空则设置为None 我尝试做variable int stringToInt or None但如果字符串为空 则会出错 而不仅仅是将其设置
  • Django模型列表顺序字段更新

    我有一张桌子 比方说Book 具有以下模型定义 class Book models Model name models CharField name of the book max length 10 sequence models Int
  • System.Threading.Tasks.Dataflow 和 Microsoft.Tpl.Dataflow 之间有什么区别

    有 2 个不同的官方 TPL Dataflow nuget 包 我很困惑选择应该使用哪一个 据我了解 System Threading Tasks Dataflow 版本比其他版本稍新 而且 System Threading Tasks D
  • 警告 - 初始化使指针来自整数而不进行强制转换

    我发现了类似的问题 但我认为它们不适用于我的具体问题 所以如果它们适用 我很抱歉 我作为一年级 CS 学生正在学习 C 并尝试用 C 进行测验 但我一无所获 因为每次我尝试编译以查看它是否正常工作时 我都会收到消息 警告 初始化使指针从未经
  • 新数据框列作为另一个数据框的函数(摘要)对我不起作用

    我想创建一个新的计算列 另一列文本的摘要 为了让您重现 我创建了一个 df 作为可重现的示例 df lt data frame name replicate 1000 paste sample LETTERS 20 replace TRUE
  • 如何添加case语句以在每条记录后添加break?

    每行之后应该有一个休息时间LIKE A 当找到下一条记录时LIKE B stmt con gt prepare SELECT FROM fistevent WHERE Event Id AND TicketType AND row name
  • 无需 jQuery 即可获得 innerWidth() 等效项

    我目前正在努力从我编写的一些代码中消除 jQuery 并且我有一部分代码 其中我正在计算某些代码的内部和外部宽度span元素 这好像是 getBoundingClientRect 对于获取元素的外部宽度效果很好 但我在获取内部宽度方面有点困
  • 如果参数有成员变量则特殊化函数

    我有一个模板化的错误报告函数 因为它可以报告许多不同消息类别的错误 template