在概念定义中,是否允许在requires表达式之外出现替换失败

In concept definitions, are substitution failures allowed outside of a requires expression?

本文关键字:表达式 外出 失败 替换 requires 定义 是否      更新时间:2023-10-16

考虑以下代码:

#include <type_traits>                                           
#include <iostream>
template <class T> concept bool C1 = std::is_same<T, int>::value; 
template <class T> concept bool C2 =  
    C1<decltype(std::declval<T>() + std::declval<T>())>; 
struct A {};                   
int main() { 
  std::cout << C2<int>; 
  std::cout << C2<A>;                                                 
  return 0;                                                           
}

GCC对其进行了精细编译并打印了10。

但是§14.10.1.2 N4553的谓词约束[temp.contr.pred]表示

谓词约束是评估常量表达式E(5.19)的约束。

然后

替换后,E应具有bool型。

由于C1<decltype(std::declval<A>() + std::declval<A>())>是一个替换失败,而不是bool类型,这是否意味着程序应该是格式错误的?

概念TS仅定义用于确定满足声明的相关约束的行为;没有关于引用相关约束之外的概念名称的规定。所以严格地说,std::cout << C<int>std::cout << C<A>都是病态的。

EWG在科纳决定允许这一新功能:

Straw民意测验:SF|F|N|A|SA

  • 我们应该允许在任何地方评估概念吗?8|6|2|0|0
  • 我们是否应该允许在任何表达式中存在和评估required表达式?1|2|10|3|1
    • 请注意,如果没有第一次轮询,第二次轮询将发生更改

但目前还没有具体说明其行为的措辞。

GCC目前允许概念作为表达式作为(我相信没有文档)扩展。我发现,当X...替换为C的初始值设定项时,很可能会指定此特性,从而使C<X...>求值为false,从而无法生成有效的表达式,否则会获得该表达式的值。这似乎是明智的做法,与海湾合作委员会的执行情况一致。