【问题标题】:C++ duplicate symbolsC++ 重复符号
【发布时间】:2015-07-08 21:40:45
【问题描述】:

(苹果机)

我尝试过命名空间,包括守卫、pragma once 等。

基本上是这样的结构:

CMakeLists.txt

add_executable(Game Game/main.cpp Game/rtexture.cpp)

游戏/main.cpp

#include "cleanup.h"

//...
cleanup(foobar);

游戏/rtexture.cpp

#include "cleanup.h"

//...
cleanup(foobar);

清理.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);
}

如果有人问,我确实从教程中获取了这个“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

有什么帮助吗?谢谢。

【问题讨论】:

  • 你在 cleanup.h 中使用#ifndef CLEANUP_H #define CLEANUP_H #endif 吗?如果没有,那么你必须使用它。
  • 不,我正在使用它 - 抱歉回复晚了。如以下答案所示,inline void 有效,但无论如何感谢。

标签: c++ macos cmake duplicates


【解决方案1】:

显式函数模板特化受单一定义规则的约束,就像常规函数一样。添加inline 以允许在标题中定义;或在源文件中定义它们,并在标题中声明。

【讨论】:

    【解决方案2】:

    我没有看到任何包含警卫。此外,由于您在多个 .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 */
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-13
      相关资源
      最近更新 更多