(Mac)
I've tried namespaces, include guards, pragma once, etc.
Basically, this is the structure:
CMakeLists.txt
add_executable(Game Game/main.cpp Game/rtexture.cpp)
Game/main.cpp
#include "cleanup.h"
//...
cleanup(foobar);
Game/rtexture.cpp
#include "cleanup.h"
//...
cleanup(foobar);
cleanup.h
//various includes
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 specializations serve to free the passed argument and also provide the
* base cases for the recursive call above, eg. when args is only a single item
* one of the specializations below will be called by
* Cleanup(std::forward<Args>(args)...), ending the recursion
* We also make it safe to pass nullptrs to handle situations where we
* don't want to bother finding out which values failed to load (and thus are null)
* but rather just want to clean everything up and let cleanup sort it out
*/
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);
}
If anyone asks, I did take this "cleanup.h" from a tutorial but can't find a way to include it in multiple classes without having it declare duplicate symbols.
Home at cruz45488-y19-MBA13-12 in ~/desktop/sdlworkspace/tmp
$ make
Linking CXX executable Game
duplicate symbol __ZN5RUtil7cleanupI10SDL_WindowJEEEvPT_DpOT0_ in:
CMakeFiles/Game.dir/Game/main.cpp.o
CMakeFiles/Game.dir/Game/rtexture.cpp.o
duplicate symbol __ZN5RUtil7cleanupI12SDL_RendererJEEEvPT_DpOT0_ in:
CMakeFiles/Game.dir/Game/main.cpp.o
CMakeFiles/Game.dir/Game/rtexture.cpp.o
duplicate symbol __ZN5RUtil7cleanupI11SDL_TextureJEEEvPT_DpOT0_ in:
CMakeFiles/Game.dir/Game/main.cpp.o
CMakeFiles/Game.dir/Game/rtexture.cpp.o
duplicate symbol __ZN5RUtil7cleanupI11SDL_SurfaceJEEEvPT_DpOT0_ in:
CMakeFiles/Game.dir/Game/main.cpp.o
CMakeFiles/Game.dir/Game/rtexture.cpp.o
Any help? Thanks.
Explicit function template specialisations are subject to the One Definition Rule, just as regular functions are. Add inline
to allow definitions in a header; or define them in a source file, with declarations in the header.
I don't see any include guards. Also, because you include this header in multiple .cpp
files, #ifdef
is not enugh - you need to use inline
keyword, that tells linker, that particular function may be defined in more than one translation units.
#ifndef CLEANUP_H
#define CLEANUP_H
//includes...
template<>
inline void cleanup<SDL_Window>(SDL_Window *win){
if (!win){
return;
}
SDL_DestroyWindow(win);
}
template<>
inline void cleanup<SDL_Renderer>(SDL_Renderer *ren){
if (!ren){
return;
}
SDL_DestroyRenderer(ren);
}
template<>
inline void cleanup<SDL_Texture>(SDL_Texture *tex){
if (!tex){
return;
}
SDL_DestroyTexture(tex);
}
template<>
inline void cleanup<SDL_Surface>(SDL_Surface *surf){
if (!surf){
return;
}
SDL_FreeSurface(surf);
}
#endif /* CLEANUP_H */
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With