在需要参数列表中,您是否可以引入导致替换失败的类型?

时间:2015-09-26 19:50:48

标签: c++ c++17 c++-concepts

例如,我可以定义像

这样的概念
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会替换失败。这是它的假设吗?

1 个答案:

答案 0 :(得分:7)

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

  

参数化约束是一个声明序列的约束   参数(8.3.5),称为约束变量,并且有一个   操作数。 [注意:参数化约束由...引入    requires-expression s(5.1.4)。参数化约束的约束变量对应于在中声明的参数    requires-expression requirement-parameter-list ,约束的操作数是约束的结合。 - 结束   注意]

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

  

如果且仅替换为,则满足参数化约束   其约束变量的类型不会导致无效   类型,其操作数是满意的。模板参数被替换   按照它们的顺序进入声明的约束变量   声明。如果替换为约束变量失败,则不再存在   执行替换,并且不满足约束。

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