Swift: generating a common FloatingPoint value for Int

Consider the following (simplified from actual code):

func roundedInt<T: FloatingPoint>(_ f: T) -> Int {
    return Int(f.rounded())
}

Unable to compile with the following error:

It is not possible to call an initializer for type 'Int' using a list of arguments of type '(T)'. Overloads for 'Int' exist with these partially matching parameter lists: (Int64), (Word), (UInt8), (Int8), (UInt16) , (Int16), (UInt32), (Int32), (UInt64), (UInt), (Int), (Float), (Double), (Float80), (String, radix: Int), (CGFloat), ( NSNumber)

I suppose this means that FloatingPoint cannot be matched with any of the Int overloads.

Is there an easy way to make this work? Or is there a limitation for generic Swift files (e.g. compared to C ++ templates) that exclude this?

+6
source share
3 answers

Simple C ++ templates are nothing more than a macro ish, a smaller type, a mechanism for replacing source code. The calling code is replaced by the applicable template, and the compiler checks to see if the resulting code makes sense. You are right, an unlimited function roundedInt<T>should work fine in C ++ land.

Swift generics instead are typical in design, that is, the general code must be sound on its own, regardless of any data from this call site. In your example, the protocol FloatingPointis the type that defines compilation (and not the actual type Tused by the calling code).

(By the way, Java / C # generics also resemble Swift style.)


, roundedInt:

func roundedInt(_ f: Float)  -> Int { ... }
func roundedInt(_ f: Double) -> Int { ... }

. , , ... /!

@Sweeper. , , , .

+2

, :

func roundedInt<T: FloatingPoint>(_ f: T) -> Int {
    return Int(Float80("\(f.rounded())")!)
}

, "". , , FloatingPoint, Float, Double Float80. . Float80. Int.

, , . , . , , , - 9223372036854775295 64- , 512 , Int.max.

, 9223372036854775295, 9223372036854770000 . , , , .

+2

Using BinaryFloatingPoint, this works as you expect, within what Int can represent.

func roundedInt<T: BinaryFloatingPoint>(_ f: T) -> Int {
   return Int(f.rounded())
}

let x = roundedInt(Float(42.1)) // 42
0
source

Source: https://habr.com/ru/post/1016897/


All Articles