stl2 icon indicating copy to clipboard operation
stl2 copied to clipboard

Cross-concept explicit/implicit override is problematic

Open timsong-cpp opened this issue 7 years ago • 1 comments

Today's discussion with Casey on Slack revealed that:

  1. The requires-expression
      requires(T t, U&& u) {
        { t = std::forward<U>(u) } -> Same<T>&&;
      }
    
    for Assignable<T&, const T&> implicitly requires variations involving assignment from non-const lvalues, const rvalues, and non-const rvalues, each with the condition that it does not modify the right operand of =.
  2. But Copyable<T>, which is Movable<T> && CopyConstructible<T> && Assignable<T&, const T&>, does not actually require move assignment to be non-modifying for the right operand of =, because it requires Movable<T> which requires Assignable<T&, T>, which counts as an explicit requirement that overrides that last variation of Assignable<T&, const T&>.

In other words, the requirements imposed by the same concept-id can vary based on what other concepts it is used with. This seems highly problematic to me: understanding a complex concept is now not just a simple matter of summing up the requirements imposed by each individual component; instead we need to keep track of which requirements are implicitly imposed and which are explicitly imposed and remember that the implicit requirement goes away - but only if the corresponding explicit requirement is simultaneously present. It also means that the requirements imposed by Copyable<T> is not a superset of the requirements imposed by Assignable<T&, const T&>, despite the former seemingly subsuming the latter on inspection (and in fact subsuming the latter in overload resolution).

I believe we should only have explicit/implicit override within the same concept, as in the [concept.lib.general.equality]p6 example. This also means that we need to have Assignable<T&, const T&> not require implicit variations - at least not for non-const rvalues - but I never really liked that in the first place: it seems rather odd for the set of expressions required by an requires-expression to be dependent on the template arguments it is instantiated with.

timsong-cpp avatar Feb 08 '18 02:02 timsong-cpp

I don't agree with Casey's interpretation. Or, if that was his interpretation from the beginning, that wasn't clear to me. We should hunt down the places where it matters and fix them so that concept definitions can be understood in isolation.

ericniebler avatar Feb 08 '18 04:02 ericniebler