访问未定义的子类型时自定义编译错误消息

2023-12-31

我有一些类型,其中每个类型都有相同名称的子类型:

struct TypeA {
    typedef int subtype;
};
struct TypeB {
    typedef float subtype;
};

以及没有此子类型但在同一上下文中使用的类型:

struct TypeC {
    // (no subtype defined)
};

如何添加一个虚拟子类型来提供自定义编译错误消息?

我的(到目前为止不成功的)尝试是:

struct TypeC {
    struct subtype {
        static_assert(false, "Attempt to access the non-existent subtype of TypeC.");
    };
};

But static_assert(false, ...)无法工作,因为即使从未访问过该类型,编译器也会抛出错误。

怎样才能延迟评估static_assert到访问类型的时间?

失败的尝试是引入一个虚拟枚举并从中构造一个表达式:

enum { X };
static_assert(X != X, "...");

具体用例:我有一个类模板List这是用子类型定义的head and tail如果非空,并且如果为空则使用这些子类型应该给出错误:

template<typename...>
struct List;

// empty list:
template<>
struct List<> {
    struct head { static_assert(false, "Attempt to access the head of an empty list."); };
    struct tail { static_assert(false, "Attempt to access the tail of an empty list."); };
};

// non-empty list:
template<typename Head, typename ...Tail>
struct List<Head, Tail...> {
    typedef Head head;
    typedef List<Tail...> tail;
};

如果我简单地省略类型head and tail,当访问例如大小为 2 的列表的第 3 个元素,代码为List<int,int>::tail::tail::head给出了不太好的消息(g++ 4.7.2):'head' is not a member of 'List<int>::tail {aka List<>}'


// empty list:
template<typename... Args>
struct List {
    struct head {static_assert(sizeof...(Args) != 0, "Attempt to access the head of an empty list."); };
    struct tail {static_assert(sizeof...(Args) != 0, "Attempt to access the tail of an empty list."); };
};

// non-empty list:
template<typename Head, typename ...Tail>
struct List<Head, Tail...> {
    typedef Head head;
    typedef List<Tail...> tail;
};

编辑:这个问题实际上涉及到 C++ 模板如何工作的三个方面:

  1. (§14.7.1 [temp.inst]/p1) 除非类模板特化已显式实例化 (14.7.2) 或显式特化 (14.7.3),否则当在需要完全定义的对象类型或类类型的完整性影响程序语义的上下文。类模板特化的隐式实例化会导致声明的隐式实例化,但不会导致类成员函数、成员类等的定义的隐式实例化。
  2. (§14.7.1 [temp.inst]/p11) 实现不应隐式实例化...不需要实例化的类模板的成员类。
  3. (§14.6 [temp.res]/p8) 如果无法为模板生成有效的专业化,并且该模板未实例化,则该模板格式错误,无需诊断。

3) 意味着static_assert表达式必须依赖于模板参数,否则可能会为模板生成“无效的专业化”,并且程序格式不正确,并且编译器可以随意报告错误(尽管他们不必这样做)。在上面的代码中,可以为第一个模板生成有效的特化,但由于部分特化而永远不会使用这样的特化。

上面给出的解决方案也依赖于 1) 和 2)。 1) 规定隐式实例化模板特化仅实例化声明 (not 定义) 的成员类,并且 2) 意味着明确禁止编译器尝试实例化head or tail如果只是使用隐式实例化List<>。请注意,如果您显式实例化,则此规则不适用List<> with template struct List<>;.

莱姆斯的答案中的解决方案有效,因为typedef不需要完整的类型,因此不会触发隐式实例化SubTypeErrorMessage<>1) 中的模板参数的使用static_assert in SubTypeErrorMessage绕过 3),作为有效的专业化(即,SubTypeErrorMessage<true>) 可以为该模板生成。

值得注意的是,在这两种情况下,实例化规则都意味着使用它仍然是合法的List<>::head or TypeC::subtype只要您不以需要完整类型的方式使用它们即可。因此像int f(List<>::head & ) { return 0; }是有效的,但完全没有意义,因为您无法实际调用该函数。如果你不定义List<>::head然而,编译器无论如何都会报告此代码的一个(可能是神秘的)错误。这就是更漂亮的错误消息的权衡:)

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

访问未定义的子类型时自定义编译错误消息 的相关文章

  • 以文化中立的方式将字符串拆分为单词

    我提出了下面的方法 旨在将可变长度的文本拆分为单词数组 以进行进一步的全文索引处理 删除停止词 然后进行词干分析 结果似乎不错 但我想听听关于这种实现对于不同语言的文本的可靠性的意见 您会建议使用正则表达式来代替吗 请注意 我选择不使用 S
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • C# 中通过 Process.Kill() 终止的进程的退出代码

    如果在我的 C 应用程序中 我正在创建一个可以正常终止或开始行为异常的子进程 在这种情况下 我通过调用 Process Kill 来终止它 但是 我想知道该进程是否已退出通常情况下 我知道我可以获得终止进程的错误代码 但是正常的退出代码是什
  • 使用 WebClient 时出现 System.Net.WebException:无法创建 SSL/TLS 安全通道

    当我执行以下代码时 System Net ServicePointManager ServerCertificateValidationCallback sender certificate chain errors gt return t
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • SolrNet连接说明

    为什么 SolrNet 连接的容器保持静态 这是一个非常大的错误 因为当我们在应用程序中向应用程序发送异步请求时 SolrNet 会表现异常 在 SolrNet 中如何避免这个问题 class P static void M string
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 这些作业之间是否存在顺序点?

    以下代码中的两个赋值之间是否存在序列点 f f x 1 1 x 2 不 没有 在这种情况下 标准确实是含糊不清的 如果你想确认这一点 gcc 有这个非常酷的选项 Wsequence point在这种情况下 它会警告您该操作可能未定义
  • 如何从两个不同的项目中获取文件夹的相对路径

    我有两个项目和一个共享库 用于从此文件夹加载图像 C MainProject Project1 Images 项目1的文件夹 C MainProject Project1 Files Bin x86 Debug 其中有project1 ex
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 是否可以在 .NET Core 中将 gRPC 与 HTTP/1.1 结合使用?

    我有两个网络服务 gRPC 客户端和 gRPC 服务器 服务器是用 NET Core编写的 然而 客户端是托管在 IIS 8 5 上的 NET Framework 4 7 2 Web 应用程序 所以它只支持HTTP 1 1 https le
  • Windows 和 Linux 上的线程

    我在互联网上看到过在 Windows 上使用 C 制作多线程应用程序的教程 以及在 Linux 上执行相同操作的其他教程 但不能同时用于两者 是否存在即使在 Linux 或 Windows 上编译也能工作的函数 您需要使用一个包含两者的实现
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

  • 将字段添加到 Woocommerce 注册表单并在管理编辑用户中

    在 WooCommerce 中 我在帐户注册表单中添加了额外的字段 1 ADD FIELDS add action woocommerce register form start add woo account registration f
  • system()的返回值不是执行程序的返回值

    我想执行一个可执行文件 其 main 返回 2 使用system 这就是我所做的 include
  • 无法添加服务引用 - 锁定/只读

    每当我去添加服务引用时 我都会收到错误 无法添加服务引用 Servicereference1 reference 错误 无法签出当前文件 该文件可能是只读的或锁定的 或者您可能需要手动检出该文件 我的项目中已经有一个服务引用 但它以某种方式
  • 如何通过 iPhone 中的 Graph API 在 facebook 上“点赞”和“评论”?

    我正在使用 graph api 显示新闻源 我对以下问题有疑问 我想为每个新闻提要帖子提供 喜欢 功能 我想为每个新闻提要帖子提供 评论 功能 有人可以帮助我如何使用 iphone 中的图形 api 解决这个问题吗 请参考我这里的回答 如何
  • 如何识别ODF文件?

    我需要能够根据文件的内容而不是文件的扩展名来识别给定文件是 ODF 文件 ODF 文件实际上是 zip 容器中 XML 文件的集合 这意味着我无法使用该文件的幻数 因为它只会表明它是一个 zip 文件 所以我真正要问的是是否有任何文件req
  • 如何检测USB键盘是否插入和拔出

    当 USB 键盘从电脑上插入和拔出时 是否有任何守护进程 工具会触发一些信号 事件 我需要在程序中知道 USB 键盘何时插入和拔出 关于如何做到这一点有什么想法吗 udev Linux 设备管理器 是轮询硬件的管理器 当它检测到有关设备的某
  • 带有 Qt::AlignCenter 的 QPainter 无法正确居中文本

    我想做一个相当简单的绘图 在圆的中心写下两段文字 我的代码 painter gt drawText QRectF 0 0 m iSize m iSize Qt AlignCenter m sAlias n m sCode where m i
  • 会话路由#destroy 操作

    我链接到会话控制器的销毁操作 如下所示 路线 rb resources sessions only new create destroy Rails 对上面的链接进行了抱怨 没有路由匹配 action gt destroy controll
  • 使用 Linq 动态添加条件连接

    我有一个基本的搜索控件 它根据下拉列表提供的预定义搜索 过滤条件列出 CRM 中的公司 每个下拉菜单的默认选择是 全部 否则用户将选择特定的项目 我希望能够根据选择动态构建 Linq 查询 在 5 个选择器中 它们提供了我可以与 Compa
  • 使用 MockMvc 测试重定向 URL 的 HTTP 状态代码

    我想使用 MockMvc 在 Spring Boot 应用程序中测试登录过程 成功登录后 用户将被重定向到 home 为了测试这一点 我使用 Test public void testLogin throws Exception Reque
  • 数据结构中的自引用 - 检查相等性

    在我最初尝试创建不相交集数据结构时 我创建了一个Point数据类型与parent指向另一个的指针Point data Point a Point value a parent Point a rank Int 要创建单例集 Point创建它
  • 捕获所有无效 URL

    我最近升级了一个网站 几乎所有 URL 都发生了变化 我已经重定向了所有这些 或者我希望如此 但其中一些可能已经被我忽略了 有没有办法以某种方式捕获所有无效 URL 并将用户发送到某个页面 并以某种方式知道该人来自哪个 URL 以便我可以记
  • 在 TextMate 中,我无法使用 Rails tmbundle 创建部分

    Applications TextMate app Contents SharedSupport Support lib ui rb 355 in to plist An object in the argument tree could
  • PyCharm 能否以正确的顺序显示变量的字段?

    我定义了一个有几个字段的数据类 当我打印它时 它们以正确的顺序显示 def test dataclass class Image width int height int pixels object image Image width 4
  • 多线程感知模式下的 BOOST 库

    可以在所谓的线程感知模式下编译 BOOST 库 如果是这样 您将看到 mt 出现在库名称中 我不明白它给了我什么以及我什么时候需要使用这种模式 它给我带来任何好处吗 更重要的是 我对在无线程感知机制中编译 BOOST Threads 库 名
  • 如何使react swiper在垂直方向滑动

    我想让主页就像我可以在莫伊莱视图中一次滑动一篇文章一样 我尝试过反应滑动器 但反应滑动器正在水平滑动帖子 我想垂直滑动帖子 知道如何制作吗 你可以给它方向 只需像这样添加方向道具
  • python有比较和交换操作吗

    试图找到python是否支持CAS操作 无锁编程 像java中的并发 Python没有这些操作 Java 具有比 Python 更复杂的并发控制 CPython 几乎每个人都使用的典型实现 有一个您需要了解的全局解释器锁 Jython 是
  • Groovy 安全取消引用运算符 (?.) 的最佳 Scala 模仿?

    我想知道 Groovy 的最好的 Scala 模仿是什么安全取消引用运算符 http groovy codehaus org Null Object Pattern 或者至少有一些接近的替代品是 I ve 简要讨论一下 http www c
  • 带/多个条件赋值

    让我们来一个M 10 x 4 x 12 矩阵 作为例子 我以M 4 val 4 0 0 1 0 0 1 1 1 0 0 0 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 1
  • 访问未定义的子类型时自定义编译错误消息

    我有一些类型 其中每个类型都有相同名称的子类型 struct TypeA typedef int subtype struct TypeB typedef float subtype 以及没有此子类型但在同一上下文中使用的类型 struct