Yes, the conversion from prvalue S{} to type const S& would bind directly, but it "is said to bind directly to the initializer expression", and the initializer expression "S{}" is not a glvalue. A bit confusing, since the reference "binds to" the lvalue resulting from the temporary materialization conversion. But I think this is intended, because I think the point is that a temporary materialization conversion is never applied to just one of the second or third operands of the conditional. If it did, automatically destroying the temporary at the end of its lifetime would depend on more than just the program counter register, causing brand new complications for compilers, particularly for stack unwinding on exception propagation.
There certainly is an implicit conversion sequence from an lvalue of type const S to type S, via the copy constructor. Otherwise we couldn't do:
struct S {};
void f(S) {}
int main() {
const S s;
f(s);
}
But in converting "S{}" to a type related to "s", wouldn't [expr.cond]/(4.3) apply, if the conversion in [expr.cond]/(4.1) is not possible? Note there have been changes to (4.3) since C++17:
C++17 N4659:
(4.3.1) if T1 and T2 are the same class type (ignoring cv-qualification), or one is a base class of the other, and T2 is at least as cv-qualified as T1, the target type is T2,
(4.3.2) otherwise, ...
(4.3.1) if T1 and T2 are the same class type (ignoring cv-qualification) and T2 is at least as cv-qualified as T1, the target type is T2,
(4.3.2) otherwise, if T2 is a base class of T1, the target type is cv1 T2, where cv1 denotes the cv-qualifiers of T1,
(4.3.3) otherwise, ...
But I don't see how that change would make any implicit conversion sequence unavailable. Which would mean both are possible and "b ? S{} : s" is ill-formed - not desirable. (It might make sense to say if both are possible and the target types are the same, the expression is a prvalue with that type; but it doesn't say that.)