在 requires 参数列表中,您可以引入导致替换失败的类型吗?

In requires parameter lists, can you introduce types that result in substitution failures?

例如,我可以定义一个概念吗

template <class Iter>                                                        
concept bool Iterator =                                                      
    requires(Iter i, typename std::iterator_traits<Iter>::value_type val,    
             typename std::iterator_traits<Iter>::reference ref) {           
  ++i;                                                                       
  // other implementation                                                    
};  

对于 gcc 6,此代码将 compile,但类似 ​​Iterator<int> 的结果也会导致 true,即使 valref 将被替换失败。这是它应该做的吗?

使用最新的 public 可用草案 N4377,这是一个 参数化约束 ([temp.constr.param]):

A parameterized constraint is a constraint that declares a sequence of parameters (8.3.5), called constraint variables, and has a single operand. [ Note: Parameterized constraints are introduced by requires-expressions (5.1.4). The constraint variables of a parameterized constraint correspond to the parameters declared in the requirement-parameter-list of a requires-expression, and the operand of the constraint is the conjunction of constraints. — end note ]

并且该部分明确考虑了约束变量 ([temp.constr.param]/2) 的替换失败:

A parameterized constraint is satisfied if and only substitution into the types of its constraint variables does not result in an invalid type, and its operand is satisfied. Template arguments are substituted into the declared constraint variables in the order in which they are declared. If substitution into a constraint variable fails, no more substitutions are performed, and the constraint is not satisfied.

您观察到的行为似乎是实现中的错误。