2016-09-04 8 views
6

Czy można zdefiniować niestandardową konwertera (converter1<T> i converter2) pomiędzy różnymi rodzajami surowego wskaźnik A* i B*,
następnie wykonać wszystkie funkcje (fa() i fb()) w danej klasy
użyć odpowiedniego konwertera (converter1<T> lub converter2)?automatyczne wywołanie niestandardowy konwerter surowych wskaźników A * <-> B *

Krótko mówiąc, chcę, aby program przekonwertował A* na B* i odwrotnie, KORZYSTAJĄC z moich własnych funkcji.
Chciałbym, aby zrobiło to automatycznie dla mojej wygody.

class Manager{ 
    void fb(B* b){ /** something complex  */ } 
    void fa(A* a){ /** different thing complex */ } 
    void testCase(){ 
     A* a= ... ; 
     fa(a); 
     fb(a); //automatic convert to B* using "converter2" (wish) 
     B* b= ... ; 
     fa(b); //automatic convert to A* using "converter1" (wish) 
     fb(b); 
    } 
    template<class T> T* converter1(B* b){ //hardcoded, non-static. 
     return this->getId<T>(b); 
     //^^^ just an example to show how custom it is, 
     // currently T=A 
    } 
    B* converter2(A* a){ //hardcoded 
     return a->getB(); 
     //^^^ just an example to show how custom it is. 
    } 
} 

Prawdziwa sprawa ma wiele A - A1, A2, A3 i tak dalej.
A i B nie są od siebie nawzajem.

Szkoda, że ​​nie ma sposobu. Myślę o konstruktorze wskaźnika.

+0

Czy A i B pochodzą od siebie? –

+0

Nie, nie są one powiązane z klasą. Dziękuję, zapomniałem, dodam to do pytania. – javaLover

+3

Krótka odpowiedź: Nie, to niemożliwe. –

Odpowiedz

5

Nie jest to niemożliwe.

Wskaźniki są wbudowanymi typami i istnieją tylko wbudowane konwersje między wbudowanymi typami. Konwersje zdefiniowane przez użytkownika działają tylko w przypadku typów zdefiniowanych przez użytkownika.

Być może zechcesz przełączyć się na własną markę inteligentnych wskaźników, aby sobie z tym poradzić.

+0

"Twoja marka inteligentnych wskaźników" <----- Czy będzie droższa (w porównaniu z moim kodem), jeśli użyję 'class APtr {A * a; } '? – javaLover

+2

@javaLover Prawdopodobnie nie. Kompilatory dobrze znoszą takie rzeczy. Spróbuj i zobacz. –

4

przez referencje (lub inteligentne kursory) to bardziej możliwe:

struct A {}; 
struct B {}; 


A& convert_to_a(A& a) { return a; } 
A convert_to_a(B const& b) { 
    // makes a new A from a B 
    return A(); 
} 

B& convert_to_b(B& b) { return b; } 
B convert_to_b(A const& a) { return B(); } 


struct Manager 
{ 
    template<class T> 
    void fa(T&& t) { 
    auto&& a = convert_to_a(t); 
    // do something with a 
    (void)a; 
    } 

    template<class T> 
    void fb(T&& t) { 
    auto&& b = convert_to_b(t); 
    // do something with b 
    (void)b; 
    } 

}; 

int main() 
{ 
    A a; 
    B b; 

    Manager m; 

    m.fa(a); 
    m.fb(a); 
    m.fa(b); 
    m.fb(b); 
} 
2

Nie jest to możliwe, jak chcesz.
W każdym razie można użyć funkcji catch-all i garść cech, aby ją zasymulować.
Wynika minimalny, przykład pracy:

#include<iostream> 

struct A {}; 
struct B {}; 

template<typename T> 
A* ToAConverter(T*) = delete; 

template<> 
A* ToAConverter<B>(B *b) { 
    // just an example 
    return new A; 
} 

struct Manager{ 
    void fa(A* a){ std::cout << "fa" << std::endl; } 

    template<typename T> 
    void fa(T *t) { 
     std::cout << "convert and forward" << std::endl; 
     fa(ToAConverter<T>(t)); 
    } 

    void testCase(){ 
     A *a = new A; 
     fa(a); 
     B *b = new B; 
     fa(b); 
    } 
}; 

int main() { 
    Manager m; 
    m.testCase(); 
} 

W przypadku, gdy nie zdefiniowano converter dla konkretnego typu, otrzymasz błąd kompilacji.
Jak widać, nie trzeba już jawnie wywoływać konwertera po wywołaniu fa.

Powiązane problemy