C++重复符号

hyp*_*rum 7 c++ macos cmake duplicates

(苹果电脑)

我尝试了名称空间,包括警卫,编译指示一次等.

基本上,这是结构:

的CMakeLists.txt

add_executable(Game Game/main.cpp Game/rtexture.cpp)
Run Code Online (Sandbox Code Playgroud)

游戏/ main.cpp中

#include "cleanup.h"

//...
cleanup(foobar);
Run Code Online (Sandbox Code Playgroud)

游戏/ rtexture.cpp

#include "cleanup.h"

//...
cleanup(foobar);
Run Code Online (Sandbox Code Playgroud)

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);
}
Run Code Online (Sandbox Code Playgroud)

如果有人问,我确实从教程中获取了这个"cleanup.h",但是没有找到将它包含在多个类中的方法,而没有声明重复的符号.

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
Run Code Online (Sandbox Code Playgroud)

有帮助吗?谢谢.

Mik*_*our 10

显式函数模板特化取决于一个定义规则,就像常规函数一样.添加inline以允许标题中的定义; 或者在源文件中定义它们,并在标题中添加声明.


Mat*_*jek 6

我没有看到任何包括警卫.此外,因为您在多个.cpp文件中包含此标头,#ifdef所以不需要 - 您需要使用inline告知链接器的关键字,可以在多个转换单元中定义特定功能.

#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 */
Run Code Online (Sandbox Code Playgroud)