如何使用自定义错误消息使概念失败 (C++20)

2024-03-21

概念非常适合查明代码行的错误“未满足约束条件”.

然而,我想知道是否可以在那里发布自定义信息消息。 static_assert 的优点正是这种可能性。用例:任何想要帮助用户弄清楚为什么某个表达式不满足约束的库。

这是一个简单的例子,只是为了有一些代码。您可能会争辩说,任何半正经的“用户”都必须能够弄清楚编译器的注释“因为 'is_base_of' 评估为 false”,但更多的自定义信息也没什么坏处。肯定会有更复杂的概念。


template<typename B, typename D> 
concept is_base_of = std::is_base_of_v<B, D>;

template <typename T, is_base_of<T> BaseType>
struct BaseWrapper { };  

int main() 
{
    class Base {};
    class Derived : public Base {};
    class C {};

    using T1 = BaseWrapper<Derived,Base>;
    using T2 = BaseWrapper<C,Base>;         // fails right here, but a custom message would be nice
}


[EWG] P1267R0:自定义约束诊断

然而,我想知道是否可以在那里发布自定义信息消息。

目前,Concepts 中没有这样的原生功能,但有一篇 WG21/SD-1 论文专门讨论了这个主题:

  • P1267R0:自定义约束诊断 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1267r0.pdf

Design

自定义诊断的标准中已经有先例:

[[deprecated("reason")]]

static_assert(cond, reason)

我们建议添加一个新属性,类似于​[[deprecated("reason")]]​,用于自定义约束诊断 消息。让我们称其为新的attribute[[reason_not_used("reason")]]​目前:

template​ <fixed_string Pattern>  
  requires Correct_Regex_Syntax<Pattern>  
  [[reason_not_used("invalid regex syntax")]]
bool​ match(string_view sv);

当此属性置于函数上时,诊断消息 将在以下情况下使用:

  • 由于任何原因(推导/替换失败、 需要子句约束失败、没有合适的转换等)。
  • 函数调用没有找到匹配的重载,从而导致编译失败。

如今,当函数调用未能找到匹配项时,C++ 编译器通常会打印出所有考虑的候选者的列表。我们设想这个新属性可以作为现有诊断的补充,就像static_assert​的诊断消息是。

[...]

未来发展方向

该属性还可以用于类和别名 为约束提供自定义诊断消息的模板 失败以及选择专业时(在班级的情况下) 模板):

template​ <​typename​ T>  
  requires FloatingPoint<T> || Integral<T>  
  [[reason_not_used("the element type must be numeric")]]
struct​ matrix {};

matrix<string> a;

#:#:​error: ​template constraint failure 
matrix<string​>​ a;​
             ^
#:#:​note: ​constraints not satisfied: ​the element type must be numeric
#:#:​note: ​within ...

该属性也可以附加到概念定义中,并使用 每当检查该概念的约束失败时。

它的观众是进化工作组(EWG),据 @DavisHerring(C++ 委员会成员)称,尽管未对外发布,但已被拒绝:

@戴维斯赫林:

[...] 该论文在 2018 年被考虑并“被拒绝”——也就是说,需要新的信息(例如“现在是 2021 年了,实际上概念错误信息仍然很糟糕”)才能再次考虑。

最近,论文的公开状态非常简短;不幸的是,对于像这样的较旧的论文,参考文献是内部的。

然而,很可能是受到 StackOverflow 问答的启发,这个话题在r/cpp https://www.reddit.com/r/cpp/,作为线程概念的定制“诊断” https://www.reddit.com/r/cpp/comments/iixi6x/custom_diagnostics_for_concepts/,其中讨论了一种替代的、更简单的概念自定义诊断方法[emphasis mine]

概念的定制“诊断”

我想“建议”概念的以下简单属性:

template <typename T> [[requirement_failed("reason")]]
concept MyConcept = /*some expression*/;

template<typename T>
concept MyConcept2 = requires(T t) {    
    /*some expression*/;
} [[requirement_failed("reason")]];

目的应该很明显:“原因”是作为编译器发出的 请注意,当不满足要求时。

Notes:

P1267R0 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1267r0.pdf, 但我认为它只是没有以足够简单的方式表达或呈现。 允许任何“需要”的定义上的属性可能会 导致一片混乱。

仅在概念定义中允许它将使事情保持干净。它 避免重复使用相同的各种功能 概念。它避免了过度使用该功能,因为不应该有 概念过多。

在我看来,作为界面一部分的概念应该提供 “诊断”消息作为最佳实践。

我认为我没有勇气、洞察力或时间将其变成正式提案,即使这是一件非常简单的事情。所以我认为, 我只是在这里提一下。也很难想象有什么 一些概念委员会尚未考虑类似的情况。

Anyway, 我想引起一些注意。

作者明确提到他/她不想就该主题发表正式论文。如果例如此 SO Q&A 的 OP 认为这是一个重要特征,一种方法是选择该主题并将其(重新)形式化为一篇论文。

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

如何使用自定义错误消息使概念失败 (C++20) 的相关文章

随机推荐

  • Selenium 2 和 JUnit4:如何捕获异常屏幕截图?

    我只想在意外异常时捕获屏幕截图 Note This answer could be outdated The answer is based on Selenium 2 15 Using 测试观察者 http kentbeck github
  • 正则表达式匹配所有字母数字和某些特殊字符?

    我正在尝试让正则表达式工作 该正则表达式将允许所有字母数字字符 大写字母和非大写字母以及数字 但也允许空格 正斜杠 破折号 并加上 我已经开始了 但到目前为止还没有成功 如果你想允许only那些 你还需要使用锚点 and a zA Z0 9
  • 了解libuv/epoll/非阻塞网络IO

    我试图了解非阻塞网络 IO 是如何工作的Node js libuv 我已经发现了fileIO 是使用完成的libuv工作线程 因此 在后台线程中 不过很多地方都说networkIO 是使用系统调用以非阻塞方式完成的 例如epoll kque
  • 使用 Delphi 通过 LDAP 进行 Active Directory 身份验证,并使用 [email protected]

    正如您从下面的代码片段中看到的 我目前正在使用 adshlp 和 ActiveDs TLB 从当前登录的用户收集有关 AD 的信息 我有一个表格 允许用户输入他们的 AD 密码 并在允许访问系统之前验证其是否正确 这很好 我现在遇到的问题是
  • 相当于 WinRT 中的可编辑组合框?

    标准 桌面 Windows 组合框具有三种样式 简单 下拉和下拉列表 下拉菜单的工作方式类似于编辑控件和组合框 而下拉列表不允许编辑 我是否遗漏了某些内容 或者 Windows 8 商店应用程序中的 XAML ComboBox 控件仅支持下
  • Cypress 通过 console.log 和命令日志来输出

    是否可以重定向或捕获赛普拉斯浏览器日志和命令日志以输出 我读了一些 Cypress githubissues https github com cypress io cypress issues 448关于这个话题 但我不知道如何让它发挥作
  • 替换宏变量中的字符串?

    我有一个宏 我在其中传递一个参数并使用它根据输入的名称定义一个新变量 define DO X x char do x var x other things 问题是如果我传入一个结构变量 它就会崩溃 DO X some struct gt t
  • 如何从 cdn THREE.js 加载 GLTFLoader

    我在弄清楚如何让 GLTFLoader 在 THREE js 中工作时遇到一些问题 我不明白如何使用 CDN 站点来托管文件 我尝试过使用网络上示例的链接 但这并没有完成我的工作 我在另一篇文章中读到 GLTFLoader 文件必须与我正在
  • 如何在与 Castle Windsor DI 容器相同的上下文中重用瞬态依赖项

    如果我有以下设置 当在同一上下文中创建对象时 如何将容器配置为使用相同的数据库 public class Database public interface IRepository Database Database get public
  • C/Unix 的参数解析助手

    我知道以下情况 尊者getopt 3 扩展的getopt long glibc s argp http www gnu org software libtool manual libc Argp htmlUnix 风格参数向量的解析器 po
  • 在类路径中包含 jar 文件

    我正在从引用一些外部 jar 文件的批处理文件运行 java 程序 我如何在我的批处理文件中包含这些 jar 文件 请帮助 看看Sun的官方文档 设置类路径 http download oracle com javase 6 docs te
  • 确定表/数据库的字符集?

    可以运行什么 T SQL 命令来查找 SQL Server 中表或数据库的字符集 编辑 服务器版本 Microsoft SQL Server 2008 R2 RTM 10 50 1600 1 X64 您可以使用检查版本 SELECT VER
  • 如何获取span标签的值

    如何获取 span 标签的值并将其发送到我的表单中到另一个页面 span span 我需要将我的跨度标记小计的内容发送到另一个页面 我想将其保存到隐藏字段中 但我发现没有办法做到这一点 我用了这个 但没有成功 function getTot
  • 如何在 OpenglES 1.x 中实现阴影(在 iPhone 上)

    如何在我的 OpenglES 1 x 场景中实现阴影 我用谷歌搜索了几个小时 找不到任何有用的东西 我可以找到这个教程 http www paulsprojects net tutorials smt smt html 但没有成功将其移植到
  • 升级到 SDK 2.3.301 后,Service Fabric Actor 或服务随机变得无法访问

    从 Service Fabric SDK 2 0 135 升级到 2 3 301 后 我们开始遇到 Service Fabric actor 或服务无法访问的情况 尽管在 Service Fabric Explorer 中显示为正常运行 一
  • 无法获取 WorksheetFunction 类的 Match 属性

    我想做的是基于 CelloSht Input Cells Rows 7 我想在另一个Sheet的 periodSheet A列中找到匹配项 并根据给定的列获取相应的值 我尝试过结合使用 Index and Match去做这个 这 Index
  • 使用 .NET MVC 控制器操作作为 HTML 的源

    我正在尝试显示与数据库中的用户关联的图片 图片字段的数据类型是image 在页面上 不幸的是下面的代码无法做到这一点 HTML img src User Picture 1 控制器动作 public byte Picture int id
  • 字典理解中的操作顺序

    我遇到了以下有趣的构造 假设您有一个列表列表 如下所示 my list captain1 foo1 bar1 foobar1 captain2 foo2 bar2 foobar2 你想用它们创建一个字典0 index 元素是键 一个方便的方
  • React Native FlatList 列之间的分隔符

    我有一个包含多列的 FlatList
  • 如何使用自定义错误消息使概念失败 (C++20)

    概念非常适合查明代码行的错误 未满足约束条件 然而 我想知道是否可以在那里发布自定义信息消息 static assert 的优点正是这种可能性 用例 任何想要帮助用户弄清楚为什么某个表达式不满足约束的库 这是一个简单的例子 只是为了有一些代