当前位置: 首页 > 知识库问答 >
问题:

当“永远正确的概念”被用来实现一个概念时,GCC不同意“铿锵”和“MSVC”

孙泳
2023-03-14

以下代码无法使用 Clang 13 和 MSVC v19.29 VS16.11 进行编译,但使用 GCC 11.2 成功编译

template <typename...>
concept always_true = true;

template <typename T>
concept refable = always_true<T&>;

static_assert(refable<void>);

宗族13:

<source>:9:1: error: static_assert failed
static_assert(refable<void>);
^             ~~~~~~~~~~~~~
<source>:9:15: note: because 'void' does not satisfy 'refable'
static_assert(refable<void>);
              ^
<source>:7:32: note: because substituted constraint expression is ill-formed: cannot form a reference to 'void'
concept refable = always_true<T&>;
                               ^

MSVC版本9.29 VS16.11:

<source>(9): error C2607: static assertion failed

地脚螺栓

GCC在这里有错吗?我期望可引用


共有1个答案

党权
2023-03-14
static_assert(refable<void>);

根据 [临时名称]/8,可参考

概念id是一个简单的模板id,其中模板名称是概念名称。概念id是类型为<code>bool</code>的prvalue,不命名模板专用化。如果指定的模板参数满足概念的规范化约束表达式([temp.constr.constr]),则概念id的计算结果为true,否则为false

因此,概念的规范化不依赖于命名概念的给定概念id中的模板参数,而是独立执行的参数;然而,概念id的使用可以是用于执行概念规范化的触发,[temp.constr.normal]/2:

[注1:当确定声明的关联约束([temp.constr.constr])以及评估命名概念专用化的id表达式([expr.prim.id])的值时,执行约束表达式的规范化。-结束注释]

约束规范化由 [temp.constr.normal]/1 涵盖,其中 /1.4 特别管理操作的示例:

表达式E的正规形式是如下定义的约束:

>

  • […]

    /1.4概念的范式-id C

    [示例1:

    template<typename T> concept A = T::value || true;
    template<typename U> concept B = A<U*>;
    template<typename V> concept C = B<V&>;
    

    B 的约束表达式的规范化是有效的,并导致 T::value(映射为 T↦U*∨为真(使用空映射),尽管表达式 T::value 对于指针类型 T 的格式不正确。C 约束表达式的规范化会导致程序格式不正确,因为它会形成无效的类型 V

    这里的关键问题是OP的例子是否会遇到

    在每个原子约束的参数映射中替换 ...。如果任何此类替换导致无效的类型或表达式,则程序格式不正确;无需诊断。

    或不。

    然而,refable的约束表达式的规范化会导致true(带有空映射),重点是此规范化约束中的空映射。因此,OP的refable的正常形式

    问题是:

    refable<void>
    

    结果是满足(< code>true)约束还是不满足(< code>false)取决于如何解释[temp . const . atomic]/3:

    若要确定是否满足原子约束,首先将参数映射和模板参数替换为其表达式。如果替换导致无效的类型或表达式,则不满足约束。[...]

    这一部分有点难以理解(尤其是强调的部分),但由于参数映射是空的,因此参数映射不会出现替换失败,我将强调的部分解释为将模板参数替换为规范化约束表达式,该表达式不包含模板参数,这意味着没有替换失败。这将证明GCC接受该计划是正确的。

  •  类似资料:
    • 英文原文:http://emberjs.com/guides/concepts/core-concepts/ 要开始学习Ember.js,首先要了解一些核心概念。 Ember.js的设计目标是能帮助广大开发者构建能与本地应用相颦美的大型Web应用。要实现这个目标需要新的工具和新的概念。我们花了很大的功夫从Cocoa、Smalltalk等本地应用框架引入了其优秀的理念。 然而,记住Web的特殊性非常

    • 概括来说,从 Saga 内触发异步操作(Side Effect)总是由 yield 一些声明式的 Effect 来完成的 (你也可以直接 yield Promise,但是这会让测试变得困难,就像我们在第一节中看到的一样)。 一个 Saga 所做的实际上是组合那些所有的 Effect,共同实现所需的控制流。 最简单的是只需把 yield 一个接一个地放置,就可对 yield 过的 Effect 进行

    • 以下概念是理解 API 文档的预备知识。它们将在整个过程中被引用,详细说明请参阅本页面。 如果你是新手,就从 入门指南 开始。 Vinyl Vinyl 是描述文件的元数据对象。Vinyl 实例的主要属性是文件系统中文件核心的 path 和 contents 核心方面。Vinyl 对象可用于描述来自多个源的文件(本地文件系统或任何远程存储选项上)。 Vinyl 适配器 Vinyl 提供了一种描述文件

    • 本页列出了Storm 的主要概念, 以及可以获取到更多信息的资源链接, 概念如下: Topologies(拓扑) Streams(流) Spouts Bolts Stream groupings(流分组) Reliability(可靠性) Tasks Workers Topologies(拓扑) 实时应用程序的逻辑被封装在 Storm topology(拓扑)中. Storm topology(拓

    • 本章帮助您了解Istio系统的不同部分及其使用的抽象。 Istio是什幺? 概述:提供Istio的概念介绍,包括其解决的问题和宏观架构。 设计目标:描述了Istio设计时坚持的核心原则。 流量管理 概述:概述Istio中的流量管理及其功能。 Pilot:引入Pilot,负责在服务网格中管理Envoy代理的分布式部署的组件。 请求路由:描述在Istio服务网格中服务之间如何路由请求。 发现和负载均衡

    • 如果一条链a创建了一条新的链b,则链a为链b的父链,链b为链a的子链。 系统初始只有一条链,它没有父链,其他的链都有父链。 每条链可以创建2条子链,分别叫做左子链和右子链。

    • 概念 对于常见的 RxJS 场景和用例的简要说明。 内容 RxJS v5 -> v6 升级 理解操作符导入

    • The Python Imaging Library handles raster images; that is, rectangles of pixel data. Bands An image can consist of one or more bands of data. The Python Imaging Library allows you to store several ban