2015-05-01 24 views
6

(Ostatnie pytanie na dole)Oddzielne definicje zmiennej liczbie argumentów szablonów

Niedawno poprosiłem a question dotyczące w jaki sposób naprawić błędy linkera (na zduplikowane symboli dotyczących wiele definicji szablonu pustkę.

Bo Używałem funkcji w wielu plikach źródłowych, zasugerowałem użycie słowa kluczowego inline, aby umożliwić deklaracje w nagłówku lub umieścić deklaracje w skompilowanym pliku źródłowym:

Po tym, jak zdałem sobie sprawę, że inline miał pewne złe reperkusje, umieściłem moje deklaracje w pliku źródłowym.

Teraz to było w porządku, z wyjątkiem zmiennej liczbie argumentów szablonów:

template<typename T, typename... Args> 
void cleanup(T *t, Args&&... args); 

znalazłem kilka oczywistych rozwiązań - ale nie o zmiennej liczbie argumentów szablony - użyj pliku .tpp (ale to się zaczęło ponownie deklarując zduplikowane symboli) lub zachować plik źródłowy i dodaj jawne wystąpienia.

Ale istnieje możliwość użycia setek kombinacji parametrów, więc nie chcę jawnie tworzyć wszystkiego.

Pytanie: Tak, jak bym go o każdej

  1. utrzymując zmiennej liczbie argumentów definicji szablonu w pliku źródłowym, OR
  2. Umieszczenie definicji w pliku .tpp bez uzyskania duplikatów i symbole ostatecznie unikaj używania inline?

Przykłady zduplikowanych/niezdefiniowanych błędów symboli dla deklaracji .tpp i umieszczenia powyższej definicji szablonu w pliku źródłowym.

duplicate symbol __Z7cleanupI10SDL_WindowJEEvPT_DpOT0_ in: 
    CMakeFiles/Game.dir/Game/main.cc.o 
    CMakeFiles/Game.dir/Game/RichTools/rtexture.cc.o 

_

Undefined symbols for architecture x86_64: 
    "void cleanup<SDL_Renderer, SDL_Window*&>(SDL_Renderer*, SDL_Window*&&&)", 
referenced from: 
cleanQuit() in main.cpp.o 
ld: symbol(s) not found for architecture x86_64 
+1

Chcesz kompilator do generowania dawałaby gdy są one używane, ale chcesz automatycznie odrzucić duplikaty? Użyj 'inline', a następnie! Wspomniałeś, że rozważałeś jego użycie, ale że miał "złe reperkusje", ale czym właściwie są? –

+0

Wygląda na to, że w pierwszym pytaniu nie zrozumiałeś odpowiedzi. Porada, aby wprowadzić plik źródłowy lub przejść do pliku źródłowego, dotyczyła wyłącznie w pełni wyspecjalizowanych funkcji - tych z pustym szablonem listy parametrów <>. – PiotrNycz

Odpowiedz

2

Porady w odpowiedzi na pierwsze pytanie: aby inline lub przenieść do pliku źródłowego tylko o swoich w pełni wyspecjalizowanych funkcji - te z pustą listą parametrów template <>.

więc zrobić:

Twój plik nagłówka:

// This shall be in header - it is not full specialization: 
template<typename T, typename... Args> 
void cleanup(T *t, Args&&... args){ 
    //Cleanup the first item in the list 
    cleanup(t); 
    //Recurse to clean up the remaining arguments 
    cleanup(std::forward<Args>(args)...); 
} 
// These shall be only declared here, and implemented in source file, 
// treat fully specialized function templates as regular functions 
template<> 
void cleanup<SDL_Window>(SDL_Window *win); 
template<> 
void cleanup<SDL_Renderer>(SDL_Renderer *ren); 
template<> 
void cleanup<SDL_Texture>(SDL_Texture *tex); 

Plik źródłowy:

template<> 
void cleanup<SDL_Window>(SDL_Window *win){ 
    if (!win){ 
     return; 
    } 
    SDL_DestroyWindow(win); 
} 
template<> 
void cleanup<SDL_Renderer>(SDL_Renderer *ren){ 
    if (!ren){ 
     return; 
    } 
    SDL_DestroyRenderer(ren); 
} 
template<> 
void cleanup<SDL_Texture>(SDL_Texture *tex){ 
    if (!tex){ 
     return; 
    } 
    SDL_DestroyTexture(tex); 
} 
template<> 
void cleanup<SDL_Surface>(SDL_Surface *surf){ 
    if (!surf){ 
     return; 
    } 
    SDL_FreeSurface(surf); 
} 
+0

Ale to oznacza, że ​​musiałbym użyć wbudowanej funkcji "nie wyspecjalizowanej", jak próbowałem to wcześniej. –

+0

@Hyperum, dlaczego tak myślisz? Po prostu spróbuj mojej rady.Dla wszystkich nie w pełni wyspecjalizowanych funkcji - po prostu muszą znajdować się w plikach nagłówkowych i mogą być wbudowane lub nie wbudowane. Linker C++ sam usuwa takie duplikaty - nie musisz się martwić. – PiotrNycz

+0

@Hyperium - istnieje również wyraźny sposób tworzenia instancji szablonu - ale jak już zauważyłeś - bardzo nieprzyjemne jest używanie ... – PiotrNycz

Powiązane problemy