在这段代码中,
template<class T, class U>
concept always_true = true;
template<class T>
concept always_true_if_tagged = always_true<T, typename T::tag>;
struct A {
using tag = int;
};
static_assert(always_true_if_tagged<A>);
static_assert(!always_true_if_tagged<int>); //GCC says this failedGCC说,第二种说法失败了。Clang和MSVC都同意编译它。
我最初以为它是不健康的,不需要诊断,因为是temp.constr.normal#1.4。
一个概念-id
C<A1, A2, ..., An>的范式是C约束表达式的正常形式,在每个原子约束的参数映射中替换了C各自的模板参数之后,如果有任何这样的替换会导致无效的类型或表达式,则程序是错误的;不需要诊断。
替换T::typename tag是always_true的参数映射,因此格式不正确;不需要诊断。
所以我的前两个问题是
其中一个解决方案是在前面检查嵌套的typename。因此,always_true的参数映射不会发生。
template<class T>
concept always_true_if_tagged =
requires {typename T::tag;}
&& always_true<T, typename T::tag>;为了确定是否满足原子约束,首先将参数映射和模板参数替换到其表达式中。如果替换导致无效类型或表达式,则不满足约束。否则,必要时将执行lvalue-rvalue转换,而
E应为bool类型的常量表达式。满足约束的当且仅当E的求值结果为true。如果在程序中的不同点,对于相同的原子约束和模板参数,满意的结果是不同的,程序是不正确的,不需要诊断。
如果我写
template<class T>
concept always_true_if_tagged = bool(always_true<T, typename T::tag>);bool(always_true<T, typename T::tag>)是一个原子约束IIUC。将T::typename tag替换为T=int会导致无效类型,因此应该格式良好,不能满足要求。
所以我最后的两个(或四个)问题是
always_true的参数映射吗?always_true在concept C = always_true<T, typename T::tag>中的使用是一种原子禁忌吗?Constr.conr#general-1说有三种不同的约束:连接、分离和原子约束。concept C = always_true<T, typename T::tag> 和 T=int 不能像这样形成良好的结构?(很可能与第二个问题相同)发布于 2022-04-14 21:21:11
typename T::tag没有用[T = int]命名有效的类型。typename int::tag是没有意义的.
从内存中,您还需要将模板专门化移到struct A下面,以便在模板中使用typename A::tag。在一个概念中,它不是一个模板实例化(参见:[temp.concept]、[temp.spec]、[temp.dep]),所以我不明白这怎么可能是一个原子约束(它是一个常量表达式吗?它如何评估任何事情)。
另请参阅:
https://stackoverflow.com/questions/71822010
复制相似问题