constexpr bool 是原子约束吗?

问题描述 投票:0回答:1

看这段代码(godbolt):

template <typename TYPE>
constexpr bool c1 = TYPE::c1;

template <typename TYPE>
constexpr bool c2 = TYPE::c2;

template <typename TYPE>
requires c1<TYPE>
struct Foo {};

template <typename TYPE>
requires c1<TYPE> && c2<TYPE>
struct Foo<TYPE> {};

此代码可以使用 MSVC 进行编译,但不能使用 gcc/clang 进行编译(注意:如果将

constexpr bool
更改为
concept
,则代码可以编译)。

示例中的部分特化是否比主模板具有更特化的约束?我试图弄清楚

c1<TYPE>
c2<TYPE>
是否是原子约束。

基于 temp.constr.normal,我预计

E1 && E2
的形式总是分为两部分,因此
c1<TYPE>
应该是原子的,并且代码应该编译。甚至,temp.constr.atomic/1有一个注释“原子约束是通过约束规范化形成的。E从来不是逻辑与表达式,也不是逻辑或表达式”。由于
c1<TYPE> && c2<TYPE>
是逻辑和表达式,因此基于此注释它不应该是原子的。

但另一方面,temp.constr.normal 对于

concept
s 有明确的规则。这个规则对于创建
concept
原子不是必要的,因为如果
E1 && E2
总是分成两部分,无论如何它们都会变成原子的。

哪个编译器是正确的?如果是gcc/clang,我的误解在哪里?

c++ language-lawyer
1个回答
0
投票

[临时构造原子]p2

两个原子约束,

e1
e2
,如果它们是由相同表达式的相同外观形成的,则它们是相同

两种声明的外观不同。即,第一个声明中的

c1<TYPE>
与第二个声明中的
c1<TYPE>
不同。

因此,两者都不能包含另一个,因此第二个模板声明并不比第一个模板声明更专业。

© www.soinside.com 2019 - 2024. All rights reserved.