The corresponding std::ops traits have both the type of right hand side operand and the type of result, while Checked* traits do not (and always assume that both operands and result have the same type). There is no real reason to make Checked* traits behave differently from std::ops traits, and having them as is hampers advanced uses of operator overloading: for example, if the scalar type (e.g. DateTime) and difference type (e.g. Duration) are distinct from each other then the current scheme wouldn't work at all.