For example, can I define a concept like
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
};
With gcc 6 this code will compile, but something like Iterator<int>
will also result to true
even though val
and ref
would be substitution failures. Is this what it's suppose to do?
Using the latest public available draft N4377, this is a parameterized constraint ([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 ]
And that section explicitly contemplates substitution failures for constraint variables ([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.
The behavior you observe appears to be a bug in the implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With