Ci sono sicuramente molti modi per farlo. Il primo modo che mi viene in mente è semplicemente l'overloading delle funzioni. Dal momento che non hai un parametro per sovraccaricare, dovrai crearne uno. Mi piacciono i puntatori, che agiscono efficacemente come un modo per passare i tipi alle funzioni.
class Foo {
//regular overload
template<typename T>
T bar(T*) { //takes a pointer with an NULL value
cout << "Called with return type: " << typeid(T).name() << endl;
T t = //... (some implementation here)
return t;
}
//shared_ptr overload - NOTE THAT T IS THE POINTEE, NOT THE SHARED_PTR
template<typename T>
std::shared_ptr<T> bar(std::shared_ptr<T>*) { //takes a pointer with an null value
cout << "Called with return type: " << typeid(T).name() << endl;
std::shared_ptr<T> t = //... (some implementation here)
return t;
}
public:
template <typename T>
T bar() {
T* overloadable_pointer = 0;
return bar(overloadable_pointer);
}
};
non ho mai sentito parlare di chiunque altro l'utilizzo di puntatori far passare tipi in giro, quindi se si sceglie di fare questo, di commentare a fondo, giusto per essere sicuri. È è codice strano.
Potrebbe essere più intuitivo utilizzare semplicemente una struttura di supporto per la specializzazione dei modelli, che è ciò che farebbero la maggior parte delle persone. Sfortunatamente, se hai bisogno di accedere ai membri di Foo
(cosa che presumibilmente fai), usare la specializzazione del modello richiede di passare tutti quei membri alla funzione o di essere amici degli aiutanti del modello. In alternativa, potresti passare una cosa di specializzazione type_traits a un altro membro, ma questo finisce semplicemente per essere una versione complessa del trucco del puntatore sopra. Molti lo trovano più normale e meno confuso, quindi ecco:
template<typename T>
struct Foo_tag {};
class Foo {
//regular overload
template<typename T>
T bar(Foo_tag<T>) {
}
//shared_ptr overload - NOTE THAT T IS THE POINTEE, NOT THE SHARED_PTR
template<typename T>
std::shared_ptr<T> bar(Foo_tag<std::shared_ptr<T>>) {
}
public:
template <typename T>
T bar() {
return bar(Foo_tag<T>{});
}
}
fonte
2014-11-13 18:24:29
I modelli di funzione non possono essere parzialmente specializzati, ma i modelli di classe possono. Creare un modello di classe wrapping che espone una funzione membro statica pubblica, specializzare parzialmente la classe e modificare la funzione membro in modo appropriato. – 0x499602D2