Явная специализация универсальной функции является быстрой

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

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

#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>() и получил: ошибка: невозможно явно специализировать универсальную функцию


person Moshe Gottlieb    schedule 02.11.2018    source источник


Ответы (1)


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

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

callF(on: A.self) // A.f()
callF(on: B.self) // B.f()
person Dávid Pásztor    schedule 02.11.2018
comment
Спасибо, я все еще хотел бы, чтобы мне не приходилось передавать тип в качестве параметра, а скорее как указание времени компиляции, которое ничего не помещает в стек, но это намного чище, чем мое решение. - person Moshe Gottlieb; 02.11.2018