Qbyte
September 28, 2022, 4:38pm
25
hborla:
In the above code, values... in the expansion pattern could mean either:
The postfix ... operator is called on each element in values, and the result is expanded pairwise with otherValues such that each argument has type (ClosedRange<T>, U)
values is expanded into each tuple passed to acceptAnything, with each element of otherValues appended onto the end of the tuple, and each argument has type (T... U)
Like the ambiguity with non-pack variadic parameters, the pack expansion interpretation of ... is preferred in expressions. This corresponds to the second meaning above. It is still possible to write code with the first meaning, by factoring out the call to the postfix closed-range operator into a function:
func acceptAnything<T...>(_: T...) {}
func ranges<T..., U...>(values: T..., otherValues: U...) where T: Comparable, length(Ts...) == length(Us...) {
func range<C: Comparable>(from comparable: C) -> ClosedRange<C> {
return comparable...
}
acceptAnything((range(from: values)..., otherValues)...)
}
Actually the suffix ... operator returns a PartialRangeFrom<C>.
I think in your code each argument has type (PartialRangeFrom<T>..., U) and in order to get (PartialRangeFrom<T>, U) we need to write
func acceptAnything<T...>(_: T...) {}
func ranges<T..., U...>(values: T..., otherValues: U...) where T: Comparable, length(Ts...) == length(Us...) {
func range<C: Comparable, V>(from comparable: C, and value: V) -> (PartialRangeFrom<C>, V) {
return (comparable..., value)
}
acceptAnything(range(from: values, and: otherValues)...)
}
1 Like