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

Reply via email to