C++ 在requires参数列表中,是否可以引入导致替换失败的类型?

C++ 在requires参数列表中,是否可以引入导致替换失败的类型?,c++,c++17,c++-concepts,C++,C++17,C++ Concepts,例如,我可以定义这样一个概念吗 template <class Iter> concept bool Iterator = requires(Iter i, typename std::iterator_traits<Iter>::value_ty

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

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                                                    
};  
模板
概念布尔迭代器=
需要(Iter i,typename std::iterator_traits::value_type val,
typename std::迭代器_traits::ref::ref{
++一,;
//其他实施
};  

在gcc 6中,此代码将被删除,但类似于
迭代器
的内容也将导致
true
,即使
val
ref
将导致替换失败。这就是它应该做的吗?

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

参数化约束是声明序列的约束 的参数(8.3.5),称为约束变量,并具有单个 操作数。[注:参数化约束由 需要表达式(5.1.4)。参数化约束的约束变量对应于 requires表达式的需求参数列表,约束的操作数是约束的连词。-结束 注]

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

当且仅当替换为时满足参数化约束 其约束变量的类型不会导致无效的 类型,并满足其操作数。模板参数被替换 按照声明的约束变量的顺序将其导入到声明的约束变量中 宣布。如果替换到约束变量失败,则不再 执行替换,但不满足约束


您观察到的行为似乎是实现中的一个bug。

我认为您不允许在requires子句或等效子句(如的第4节所述)之外编写
迭代器
,但我现在找不到这样的措辞。