仅具有标头实现的重复符号[重复]
Posted
技术标签:
【中文标题】仅具有标头实现的重复符号[重复]【英文标题】:Duplicate symbols with header only implementation [duplicate] 【发布时间】:2012-11-07 00:01:50 【问题描述】:我有一个在头文件中声明和实现的 C++ 类。我之所以选择这个,是因为由于_GLIBCXX_DEBUG
和预编译的库,人们无法在调试和发布版本之间轻松移动。比如我定义_GLIBCXX_DEBUG
,Boost会因为源文件的ABI变化而崩溃。
仅标题的实现产生了重复符号的问题。例如,在operator==
和非成员swap
下面的类中将产生多重定义的符号。
// Foo.hpp
namespace Bar
template
class Foo
...
;
bool operator==(const Foo& a, const Foo& b)
..
namespace std
template <>
void swap(Bar::Foo& a, Bar::Foo& b)
a.swap(b);
当声明和实现被拆分时,文件(Foo.hpp和Foo.cpp)编译和链接OK。
有什么诀窍可以让它正确编译和链接?
【问题讨论】:
我的猜测是头文件必须是内联函数 【参考方案1】:inline bool operator==(const Foo& a, const Foo& b)
..
成员函数是隐式内联的,前提是它们是在类中定义的。对它们来说也是如此:如果它们可以毫不费力地放入标题中,那么您确实可以这样做。
因为函数的代码放在头部并且可见,所以编译器能够内联调用它们,即直接将函数的代码放在调用位置(不是因为你在它前面放了inline , 但更多是因为编译器会以这种方式决定。仅将 inline 放入是对编译器的提示)。这可以提高性能,因为编译器现在可以看到参数与函数局部变量匹配的位置,以及参数不相互别名的位置 - 最后但同样重要的是,不再需要函数帧分配。
【讨论】:
完美,谢谢。我尝试输入static
而不是inline
伙计,三年后我才提出自己的问题......现在我在仅标题的实现中有一个数据成员,导致同样的错误。数据成员是static
,它在头文件中初始化(但在类声明之外),因为没有实现文件。我该如何解决这个问题(或者我应该问一个新问题)。
在How to have static data members in a header-only library? 找到它。其中一些愚蠢的 C++ 语言规则有时令人抓狂……
谢谢。添加显式内联也解决了我的问题。以上是关于仅具有标头实现的重复符号[重复]的主要内容,如果未能解决你的问题,请参考以下文章