Dynamic dispatch with generics

I have the following class structure:

 

protocol DoSomething { init()}

class ClassA: DoSomething { required init() {} }
class ClassB: DoSomething { required init() {} }


class ClassC {
    var val:T

    init() { val = T() }
    func doSomething() { print("default called.") }
}

extension ClassC where T:ClassA {
    func doSomething() {
        print("ClassC[ClassA].doSomething")
    }
}

extension ClassC where T:ClassB {
    func doSomething() {
        print("ClassC[ClassB].doSomething")
    }
}

 

Where the extensions provide specialization of ClassC depending on the generic called. The following works:

 

let a = ClassC()
let b = ClassC()

a.doSomething() // got: "ClassC[ClassA].doSomething" (correct function called)
b.doSomething() // got: "ClassC[ClassB].doSomething" (correct function called)

 

Because `doSomething` is defined as a method in class C, Swift can dynamically dispatch to the correct function defined in the extension. However, If try to define a class that uses `ClassC`, things stop working:

 

class ClassD {
    func apply(val:ClassC) {
        val.doSomething()
    }
}

let d_a = ClassD()
let d_b = ClassD()

d_a.apply(val: a) // got: "default called." (incorrect function called)
d_b.apply(val: b) // got: "default called." (incorrect function called)

 

Which would seem to indicate that in `apply` the function `doSomething is no longer dynamically dispatched. Is this expected behavior, and will Swift not do a vtable lookup when the call does not originate from a method within the class or is this a bug?

 

Thanks!

Powered by WPeMatico

About

You may also like...

Comments are closed.