Description
While trying to fix an issue with some type traits in Clang (llvm/llvm-project#132044), I noticed that std::common_type
has notably different language in the standard than other traits that are handled in the same way. The type traits
std::is_constructible
and variants,std::is_convertible
and variants,std::is_assignable
and variants,std:reference_{constructs,converts}_from_temporary
are all defined based on some snippet of code being "well-formed", where it is additionally stipulated that "only the validity of the immediate context is considered." (See [meta.unary.prop], [meta.rel].)
However, the corresponding clause for std::common_type
in [meta.trans.other] sounds like this:
Otherwise, if
decay_t<decltype(false ? declval<D1>() : declval<D2>())>
denotes a valid type, let C denote that type.
Why not similar language as for the other type traits? The implementation in Clang seems to apply the same semantics for all these traits.