Reputation: 22272
I have value types to represent Duration and Frequency (inverted Durations). Wanting to do math with them, I have among others the following operator overload:
func * (a:Frequency, b:Duration) -> Double {
return a.numerator * (b / a.denominator)
}
Because I use these often with graphics code, I found myself often needing a CGFloat
response rather than a Double
. So I added the following sugar:
func * (a:Frequency, b:Duration) -> CGFloat {
return CGFloat(a * b)
}
This worked fine in Swift2.2. The compiler seemed to find and apply the appropriate one based on the expected return type. But with Swift3, this appears to no longer be the case? I get an Ambiguous use of operator '*'
error. It even tells me that it found two candidates, the original function as well as the one that's erroring.
Is this to be expected with changes coming in Swift3? Is it something I got away with before but should not have? Or a regression?
UPDATE
You don't even need your own special classes to do this. In an XCode7 playground, the following is fine:
func * (a:String, b:Double) -> Double {
return Double(a)! * b
}
func * (a:String, b:Double) -> CGFloat {
return CGFloat(a * b)
}
let x:CGFloat = "4.2" * 3.0
let y:Double = "-1.1" * 22.2
But fails with the above mentioned error in XCode8
Upvotes: 1
Views: 222
Reputation: 15350
I think it was a bug in the previous version of the compiler.
It's not possible to determinate if want to use the func * (a:String, b:Double) -> Double
func or it's a recursive call to func * (a:String, b:Double) -> CGFloat
(Yep, there is a constructor for CGFloat that takes a CGFloat as a parameter).
If you implement the code like this (making explicit which function you really want), the compile will be able to infer the correctly function:
func * (a:String, b:Double) -> CGFloat {
let result: Double = a * Double(b)
return CGFloat(result)
}
Upvotes: 1