Swift generics are not like C++ templates; they are built on dynamic dispatch at runtime instead of instantiation, much like Java interfaces. Overload resolution, on the other hand, happens at compile-time, with "more specific” overloads being preferred over “less specific” ones. (The exact ordering rules have not been written down anywhere.) So the behavior you’re seeing is by design: if you want static dispatch you can use overloads, and if you want dynamic dispatch you use a protocol.
Jordan > On Jun 9, 2016, at 07:23, apetro...@outlook.com via swift-users > <swift-users@swift.org> wrote: > > Hi Ian, > > You're right, if there's a function that's specialized everything works well > (actually, I deleted exactly the same function from my example, in an attempt > to be brief and succinct :) ). But that kind of ruins the whole point of > interface specialization and violates the principle of least surprise, don't > you think? > > I don't have enough knowledge about how Swift compiler implements generics to > speculate is the "right" solution possible or not. If the compiler emits > different implementations for functions testPrint<Int> and testPrint<String>, > then it definitely have enought info to pick the right specialized > implementation, and this is a bug; If not... well, then it's probably best to > remove the whole feature from the language. > > Alex > > On June 9, 2016 at 16:05:47, Ian Terrell (ian.terr...@gmail.com > <mailto:ian.terr...@gmail.com>) wrote: > >> Hi Alex, >> >> This is definitely a little confusing. I think it may be intentional >> behavior though. >> >> I don't believe it's tied to scope, but tied to the fact (I think!) that all >> generic specialization methods are statically dispatched. >> >> Although it looks like the printMe method chosen would be based on the T of >> the specialized class at runtime, it's actually based on the T of the >> printPrinter method at compile time. At that time printPrinter has no >> information about T, and so it is tied to the general version of printMe. >> You can see that if you add a specialized printPrinter method: >> >> func printPrinter<T: SignedIntegerType>(printer: PrintClass<T>) { >> printer.printMe() >> testPrint(printer.value) >> } >> >> Now the further constrained version of printPrinter is called, which calls >> the further contrained version of printMe. >> >> I hope this helps! And I hope if I got anything wrong someone chimes in to >> correct me. :) >> >> Ian >> >> >> >> >> >> On Wed, Jun 8, 2016 at 4:44 PM, Aleksandar Petrovic via swift-users >> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote: >> Hi swift-users, >> >> I'm trying achieve something similar to C++ template specialization with >> protocol extensions, and I found a strange behavior: >> >> // ---------- >> >> protocol Printer { >> associatedtype TestType >> var value: TestType { get } >> func printMe() >> } >> >> extension Printer { >> func printMe() { >> print("Base printer: \(value)") >> } >> } >> >> extension Printer where TestType: SignedIntegerType { >> func printMe() { >> print("Int printer: \(value)") >> } >> } >> >> func testPrint<T>(value: T) { >> print("testPrint") >> } >> >> func testPrint<T where T:SignedIntegerType>(value: T) { >> print("testPrint for int") >> } >> >> >> class PrintClass<T>: Printer { >> var value: T >> init(value: T) { self.value = value } >> } >> >> func printPrinter<T>(printer: PrintClass<T>) { >> printer.printMe() >> testPrint(printer.value) >> } >> >> >> let intPrinter = PrintClass(value: 42) >> let stringPrinter = PrintClass(value: "test value") >> >> intPrinter.printMe() // Int printer: 42 >> stringPrinter.printMe() // Base printer: test value >> >> testPrint(intPrinter.value) // testPrint for int >> testPrint(stringPrinter.value) // testPrint >> >> printPrinter(intPrinter) // Base printer: 42 (!!!) >> // testPrint >> (!!!) >> >> // ---------- >> >> The compiler correctly chooses specialized protocol extension as long as the >> function call is in the same scope with the object declaration. But all >> knowledge about types seems to be lost in the last line, when the scope is >> changed, in function printPrinter(). >> >> Is this a bug or desired behaviour? >> >> Alex >> >> >> _______________________________________________ >> swift-users mailing list >> swift-users@swift.org <mailto:swift-users@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-users >> <https://lists.swift.org/mailman/listinfo/swift-users> >> > _______________________________________________ > swift-users mailing list > swift-users@swift.org <mailto:swift-users@swift.org> > https://lists.swift.org/mailman/listinfo/swift-users > <https://lists.swift.org/mailman/listinfo/swift-users>
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users