为什么未验证模板模板参数中的概念?

C++20 允许程序为模板模板参数指定概念。例如,

#include <concepts>

template <typename T> concept Char = std::same_as<T, char>;
template <typename> struct S {};
template <template <Char U> typename T, typename U> T<U> foo() { return {}; }

int main() { foo<S, int>(); }

函数的第一个模板参数foo应该是一个单参数模板。

该概念Char仅被定义为 true 类型char,因此尝试满足它 forint将失败。以上程序被所有编译器接受:https : //gcc.godbolt.org/z/PaeETh6GP

能否请您解释一下,为什么可以指定模板模板参数中的概念,但仍然会被忽略?

回答

模板(实际)参数匹配模板(形式)参数,如果后者至少与前者一样专业

template <Char> typename T专业比template <typename> struct S。粗略地说,template <Char>accepts 的一个子集template <typename>(“至少作为专业化”实际上意味着什么的确切定义相当复杂,但这是第零个近似值)。

这意味着可以在可以使用形式参数的所有上下文中使用实际参数。也就是说,对于任何K对其T<K>有效的类型,S<K>也是有效的(因为S<K>对 any 有效K)。

因此,它是确定替代ST

如果你反过来做:

template<typename T> concept Any = true; 
template<typename T> concept Char = Any<T> && std::same_as<T, char>;

template<template<Any> class T> void foo();
          
template<Char> struct S { };
          
int main()  
{           
    foo<S>(); 
}

那么这是格式错误的,因为(大致)您可以说T<int>但不能说S<int>。所以S不是 的有效替代品T

笔记:

  1. 为什么我们需要这个永远真实的概念Any?简单地说有什么问题template <template <typename> typename>?嗯,这是因为一个特殊的规则:如果参数根本没有约束,参数的约束将被忽略,一切正常。
  2. 为什么要写Any<T> && std::same_as<T, char>;?为了说明一个观点。实际规则不评估约束的布尔值,而是将约束作为公式进行比较,其中原子约束作为变量,请参见此处。因此,正式的原因是S具有比 严格更大(包含方面)的原子约束集的合取T。如果S有相同或严格较小的集合,它将是格式良好的。如果两个集合不是按包含排序,那么两个模板都不是更特化的,并且没有匹配。

以上是为什么未验证模板模板参数中的概念?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>