2012-06-13 16 views
10

Czy istnieje sposób określenia typu zmiennej przekazanej do szablonu i wywołania funkcji na podstawie tego, czy jest to int lub std::string itd ...?Wykonywanie różnych metod w oparciu o zmienną typu szablonu

Na przykład

template <class T> 
struct Jam 
{ 
    Jam(T *var) 
    { 
     if (typeid(var) == typeid(std::string*) 
       *var = "Hello!"; 
     else if (typeid(var) == typeid(int*) 
       *var = 25; 
    } 
}; 

Kiedy próbuję użyć tego kodu, pojawia się błąd invalid conversion from const char* to int. Podejrzewam, że dzieje się tak dlatego, że kompilator "rozszerza" szablon na oddzielne funkcje i kiedy podałem nowe wystąpienie struktury throw Jam<std::string>(&setme);, wykrył on oświadczenie var* = 25 i odmówił kompilacji.

Czy jest to właściwy sposób? Może z ochroną makr? Dzięki.

Odpowiedz

12

regularne funkcja przeciążenia zamiast:

template <class T> 
struct Jam 
{ 
    Jam(std::string* var) 
    { 
     *var = "Hello!"; 
    } 

    Jam(int* var) 
    { 
     *var = 25; 
    } 
}; 

chyba że chcesz się specjalizować typu T użyte do wystąpienia Jam. W takim przypadku należy wykonać:

template<> 
struct Jam<std::string> 
{ 
    Jam(std::string* var) 
    { 
     *var = "Hello!"; 
    } 
}; 

template<> 
struct Jam<int> 
{ 
    Jam(int* var) 
    { 
     *var = 25; 
    } 
}; 


template<typename T> 
struct Jam 
{ 
    Jam(T* var) 
    { 
     // every other type 
    } 
}; 
+1

Istnieją inne alternatywy, jak na przykład specjalizowanie tylko konstruktora ('template <> Jam :: Jam (int * var) {}' poza definicją klasy szablonu) lub bardziej złożone SFINAE w celu włączenia/wyłączenia kodu na argumentach szablonu ... Nie sądzę, żeby miało to sens w tym prostym problemie, ale może mieć sens, gdy te proste rozwiązania staną się ciężarem (powiedzmy, że konstruktor zrobił 100 rzeczy, z których tylko jedna jest zależna od typu lub że było 100 innych funkcji składowych i specjalizacja całego typu byłaby kosztowna) –

6

Wyszukiwanie "częściowej specjalizacji szablonów".

Weź Jam() 's ciało z Jam {}:

template <class T> 
struct Jam 
{ 
    Jam(T *var); 
}; 

Teraz napisać dwa ciała:

Jam<int>::Jam(int *var) { 
    // stuff 
} 

Jam<std::string>::Jam(std::string *var) { 
    // stuff 
} 

(Ostrzeżenie:. Rusty C++ Ale to ogólnie, jak to zrobić.)

Nowe pytanie: Jeśli potrzebujesz pisania na klawiaturze, dlaczego używasz C++? Przestawiłbym się na Ruby i zapisał C++ dla wtyczek, które wymagają szybkości. Ale C++ nadal obsługuje eleganckie projekty, z większą ilością pracy!

+1

+1, chociaż nie jest to tak zwane * częściowe * specjalizacji szablonów. Specjalizacja * częściowego * w * częściowego szablonu * zwykle odnosi się do faktu, że specjalizacja jest stosowana tylko do podzbioru typów, w porównaniu do * pełnej specjalizacji *, dla której wszystkie argumenty szablonu są stałe. –

+2

Holy crap. Znałem C++? Nadzieja, że ​​nic nie wybuchło! – Phlip

+0

@Phlip Właśnie użyłem twojego kodu w wystrzeliwaniu promu kosmicznego. Wpadł w ogień, zabił wszystkich w środku i zniszczył miasto, wszystko z powodu twojego kodu. Wielkie dzięki. – Andrew

Powiązane problemy