(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.
I don't see any include guards. Also, because you include this header in multiple
.cpp
files,#ifdef
is not enugh - you need to useinline
keyword, that tells linker, that particular function may be defined in more than one translation units.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.