Явно специализировать универсальную функцию является быстрой - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь вызвать статический метод для класса swift, используя обобщенную функцию, поэтому мне не нужно, чтобы тип класса был частью сигнатуры функции.
Не могу найти способ сделать это.

Вот пример того, что я пытаюсь сделать на C ++:

#include <iostream>

class A {
public:
    static void f(){
        std::cout << "A::f()" << std::endl;
    }
};

class B {
public:
    static void f(){
        std::cout << "B::f()" << std::endl;
    }
};

template <typename T>
void callF(){
    T::f();
}

int main(){
    callF<A>();
    callF<B>();
    return 0;
}

Здесь я использую явную специализацию для callF с нужным мне типом.
Я понимаю, что дженерики swift не являются шаблонами, и я не могу просто вызывать все, что я хочу, и позволить компилятору прерваться, если он недействителен, поэтому я добавил протокол и заставил дженерик-параметр требовать соответствия протоколу (P в следующем пример), но я не могу найти способ сказать компилятору, что я хочу использовать определенный тип без включения его в сигнатуру функции.
Это самый чистый метод, который я придумал:

protocol P{
    static func f();
}

class A : P {
    static func f(){
        print("A.f()")
    }
}

class B : P {
    static func f(){
        print("B.f()")
    }
}

func callF<T:P>() -> T? {
    T.f()
    return nil
}

let _:A? = callF()
let _:B? = callF()

Мне действительно не нравится использовать пустышки в моем коде, но я не могу обойти это.
Любые мысли о том, как избежать использования манекенов в сигнатуре функции и быстро выяснить, какой тип я хочу использовать? Я, очевидно, попытался callF<A>() и получил: ошибка: не может явно специализировать универсальную функцию

1 Ответ

0 голосов
/ 02 ноября 2018

Вы должны передать тип, который вы хотите f(), для вызова в функцию callF в качестве входного аргумента.

func callF<T:P>(on type:T.Type) {
    type.f()
}

callF(on: A.self) // A.f()
callF(on: B.self) // B.f()
...